Compare commits
1531 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e484904e3b | ||
|
|
24047c933a | ||
|
|
41fba80cb5 | ||
|
|
abc60bb235 | ||
|
|
c9f93a82ce | ||
|
|
39c4d9ad50 | ||
|
|
2121e78b45 | ||
|
|
2580aad939 | ||
|
|
368d675f24 | ||
|
|
55a676e85d | ||
|
|
8d028e6948 | ||
|
|
70eb45e923 | ||
|
|
7b42ad5e2a | ||
|
|
f6f505d487 | ||
|
|
91db5a854f | ||
|
|
b7c1b9f42b | ||
|
|
f83717255f | ||
|
|
d593ebfa34 | ||
|
|
3bdeb8e8a8 | ||
|
|
b8d2bd578c | ||
|
|
6c93dc1d82 | ||
|
|
733b8e75ac | ||
|
|
7e66eb08cf | ||
|
|
b51615be20 | ||
|
|
0261f13670 | ||
|
|
ceade84fb0 | ||
|
|
765a4749c9 | ||
|
|
50f03d83c0 | ||
|
|
110f502960 | ||
|
|
11358746da | ||
|
|
e2a9d83b3e | ||
|
|
0909bf1133 | ||
|
|
a2f7bee568 | ||
|
|
97809b3a22 | ||
|
|
ab2f06d64e | ||
|
|
ab29c73ff5 | ||
|
|
f960a79118 | ||
|
|
4cbf8b16b6 | ||
|
|
c1d5f33a4c | ||
|
|
f52b97d588 | ||
|
|
158a434899 | ||
|
|
fed6639e44 | ||
|
|
75c1e74e48 | ||
|
|
70e008bf98 | ||
|
|
e22e8d92b8 | ||
|
|
d51b0f8701 | ||
|
|
adb535421d | ||
|
|
3a54d4b4ab | ||
|
|
0b70e32f15 | ||
|
|
6f027c5535 | ||
|
|
2bc966ad24 | ||
|
|
09e7017f06 | ||
|
|
eacd1d7eb9 | ||
|
|
469ef079b9 | ||
|
|
121de1fc12 | ||
|
|
345c5c751c | ||
|
|
fd76b7bf20 | ||
|
|
7e7190ce6e | ||
|
|
5a8ab82257 | ||
|
|
fec3b6c79f | ||
|
|
dd711d51c0 | ||
|
|
d5e6f9950d | ||
|
|
e7cf0b716d | ||
|
|
d269b66623 | ||
|
|
9e6e801d49 | ||
|
|
c67563dfe4 | ||
|
|
11604ae5de | ||
|
|
45f3a171be | ||
|
|
15fea2ef54 | ||
|
|
3005b9dd2c | ||
|
|
273f57d5a2 | ||
|
|
99bda78f37 | ||
|
|
9f897f0e2c | ||
|
|
e9330f8a87 | ||
|
|
59a7c1cd9c | ||
|
|
fc4fcc9450 | ||
|
|
b16bb264cc | ||
|
|
5ad2e32712 | ||
|
|
987ab9c07f | ||
|
|
1a3e2ff18e | ||
|
|
add9bb9945 | ||
|
|
da55a4a51c | ||
|
|
82ecdd1079 | ||
|
|
1fe3bf8357 | ||
|
|
7e11ab9e95 | ||
|
|
7c7722a049 | ||
|
|
6d0fee3de9 | ||
|
|
9ce24b7ec5 | ||
|
|
e2255f419d | ||
|
|
b07ab02f54 | ||
|
|
03272c8875 | ||
|
|
1965224912 | ||
|
|
2d6bc052ab | ||
|
|
201647e1cf | ||
|
|
20fe807271 | ||
|
|
b3c78b0ca5 | ||
|
|
c14601f7c2 | ||
|
|
ac84e02018 | ||
|
|
bbf24b4994 | ||
|
|
f63286b333 | ||
|
|
92cc65bf5e | ||
|
|
60f1bada3d | ||
|
|
41a0681768 | ||
|
|
fa05647068 | ||
|
|
303840f729 | ||
|
|
779f697ffb | ||
|
|
524fdf033d | ||
|
|
441b564afe | ||
|
|
1705167998 | ||
|
|
b20886a481 | ||
|
|
cfa3766bc7 | ||
|
|
ea4f2ec7a7 | ||
|
|
97c340be54 | ||
|
|
afc137bb3f | ||
|
|
db497ccf57 | ||
|
|
2916d9353e | ||
|
|
d526d388ef | ||
|
|
43ed77f4d5 | ||
|
|
ef6549ce32 | ||
|
|
f1cf73b8af | ||
|
|
40133643c0 | ||
|
|
91b3cdde39 | ||
|
|
712c46a74e | ||
|
|
835240fda1 | ||
|
|
00b223f2a4 | ||
|
|
212faab988 | ||
|
|
f87a967c0d | ||
|
|
5dd957f117 | ||
|
|
0eeddb0607 | ||
|
|
c2b3322594 | ||
|
|
4be1d057bc | ||
|
|
06730d1a7e | ||
|
|
fc642019b3 | ||
|
|
7ef75fef4f | ||
|
|
45e6c3f2e4 | ||
|
|
707f3959f9 | ||
|
|
554a03d569 | ||
|
|
0866685971 | ||
|
|
bb528a4398 | ||
|
|
4179730552 | ||
|
|
9ff1c8b879 | ||
|
|
07850410b5 | ||
|
|
13d55cbeba | ||
|
|
1dbaa19e99 | ||
|
|
b0459b08b6 | ||
|
|
20cdb35172 | ||
|
|
9bce5d479a | ||
|
|
ce7966b750 | ||
|
|
655e0bc30d | ||
|
|
2ae966fe6b | ||
|
|
e08f4316ab | ||
|
|
ca71bf00c2 | ||
|
|
98641d5d54 | ||
|
|
aac7fa84c2 | ||
|
|
e93bddcbed | ||
|
|
d345630b2c | ||
|
|
8c09a3c6af | ||
|
|
e6ee833d45 | ||
|
|
7de15e7acd | ||
|
|
5a8308109b | ||
|
|
7dfef31469 | ||
|
|
96d302aa42 | ||
|
|
df93ebb8f6 | ||
|
|
d2c7ee8b45 | ||
|
|
50caf98cd6 | ||
|
|
78e1804381 | ||
|
|
95bd81ee7e | ||
|
|
06a73061ce | ||
|
|
933ca23348 | ||
|
|
bede980527 | ||
|
|
63dcd7ba32 | ||
|
|
e8ef74156a | ||
|
|
e3f4022ffa | ||
|
|
b4356107ed | ||
|
|
dd42577a2a | ||
|
|
f52e055414 | ||
|
|
65d750b190 | ||
|
|
661e135778 | ||
|
|
f6713559e9 | ||
|
|
394d8afa17 | ||
|
|
4e0269b3d0 | ||
|
|
58c07f8054 | ||
|
|
380eec10fb | ||
|
|
b9b5f13624 | ||
|
|
6153beabff | ||
|
|
00e5fc1632 | ||
|
|
4cd7dec92b | ||
|
|
c4dceaf3e9 | ||
|
|
32b513a025 | ||
|
|
db39bab95b | ||
|
|
565786ead1 | ||
|
|
0e3a9b28bd | ||
|
|
28eec629ec | ||
|
|
bc2d26464f | ||
|
|
e725a2915e | ||
|
|
d1d09d7c18 | ||
|
|
5cf556fa09 | ||
|
|
c718bc4214 | ||
|
|
6e72ec2e12 | ||
|
|
3fac86158c | ||
|
|
17067de2dc | ||
|
|
b667c81f84 | ||
|
|
b800320a49 | ||
|
|
425db80fea | ||
|
|
43c0c4ce91 | ||
|
|
79f6883bdf | ||
|
|
3effb23f08 | ||
|
|
9ffa700c97 | ||
|
|
198ef8feb0 | ||
|
|
fcd343af69 | ||
|
|
11856180aa | ||
|
|
4060db34fa | ||
|
|
ab21a74bfc | ||
|
|
bbe81a86f5 | ||
|
|
1c0f222028 | ||
|
|
cfd24e0f09 | ||
|
|
c2c9d53000 | ||
|
|
8eff717612 | ||
|
|
c509378b24 | ||
|
|
df8595b72e | ||
|
|
6525ccc384 | ||
|
|
7617f560ab | ||
|
|
4990af9cfd | ||
|
|
09c8be1673 | ||
|
|
186c3ef88a | ||
|
|
ad03c27805 | ||
|
|
c9ab38d449 | ||
|
|
cef61db77f | ||
|
|
c0c32c4b70 | ||
|
|
620849607e | ||
|
|
180d1862a8 | ||
|
|
6ee8cc5798 | ||
|
|
f3b7102034 | ||
|
|
13e0bc2742 | ||
|
|
a4b49e3fc2 | ||
|
|
e2659b801a | ||
|
|
c3e63e7ab7 | ||
|
|
d27b329afb | ||
|
|
e187e642c0 | ||
|
|
fd21197d2a | ||
|
|
34cf0329ab | ||
|
|
94a0040ddb | ||
|
|
9d6d8da54d | ||
|
|
8e08e98c61 | ||
|
|
3036f74b69 | ||
|
|
2ad9476961 | ||
|
|
13e032fb04 | ||
|
|
803e92020b | ||
|
|
b6cbed838f | ||
|
|
19314b6686 | ||
|
|
5d329d9e55 | ||
|
|
4851cc174e | ||
|
|
78bb94eb42 | ||
|
|
c6aa1bb3ea | ||
|
|
489f17b6b2 | ||
|
|
b2b24cee7a | ||
|
|
ef35aa7954 | ||
|
|
8f5c58ff3c | ||
|
|
408811c319 | ||
|
|
1555d70230 | ||
|
|
b9da20f0d6 | ||
|
|
041481db89 | ||
|
|
beeef8d5b9 | ||
|
|
8d09539fcc | ||
|
|
07bc115b1c | ||
|
|
00cb7a0e51 | ||
|
|
657484fedc | ||
|
|
3b86a39293 | ||
|
|
49eb78db27 | ||
|
|
dbf646f266 | ||
|
|
76f3dc9e19 | ||
|
|
994dfc5b29 | ||
|
|
2b9c0e34c7 | ||
|
|
4c33328906 | ||
|
|
ff3910a705 | ||
|
|
e01dd3292f | ||
|
|
833a6e8acf | ||
|
|
3c544bceb3 | ||
|
|
036328c3ac | ||
|
|
14a2788ac4 | ||
|
|
6123c9b80a | ||
|
|
dbdd0ec4f1 | ||
|
|
0f54a2777e | ||
|
|
49c872c86d | ||
|
|
6bf661e079 | ||
|
|
ef4c7d9433 | ||
|
|
c3c34deb10 | ||
|
|
4cc35d6c66 | ||
|
|
e83befcb6b | ||
|
|
bb527b6ed1 | ||
|
|
cd6bda876d | ||
|
|
51cbb8d6bd | ||
|
|
8cc601c3e2 | ||
|
|
dc3f33717c | ||
|
|
2f5ab6f8e8 | ||
|
|
7a319d26d5 | ||
|
|
5d3341bc00 | ||
|
|
7ca767275f | ||
|
|
86a0536131 | ||
|
|
4d3fb7affe | ||
|
|
c7fcaa8e5b | ||
|
|
8ec5915b7c | ||
|
|
a31ba15dbc | ||
|
|
f147a734b1 | ||
|
|
43bb5d6e39 | ||
|
|
c6c343a45b | ||
|
|
b40e8fb508 | ||
|
|
6725c17f01 | ||
|
|
24efffc68a | ||
|
|
c92c68dee2 | ||
|
|
1eb142535c | ||
|
|
b901e57c55 | ||
|
|
0742610674 | ||
|
|
655c9348de | ||
|
|
0a8147a9da | ||
|
|
5180fbfc23 | ||
|
|
0759f2dae8 | ||
|
|
c799f9f7eb | ||
|
|
69c43947ed | ||
|
|
f95830fe23 | ||
|
|
491af1cbf0 | ||
|
|
b1892eb238 | ||
|
|
2d0e3daef3 | ||
|
|
8a76b5d1d2 | ||
|
|
88ce171f1e | ||
|
|
1d4858ae85 | ||
|
|
cff7a2a464 | ||
|
|
c18b156d8b | ||
|
|
2a177c6614 | ||
|
|
085d6cc806 | ||
|
|
818734878d | ||
|
|
2d7ab61c6e | ||
|
|
dd6f95cd33 | ||
|
|
d5482e6c74 | ||
|
|
baab1d81a7 | ||
|
|
ea114986be | ||
|
|
c1e6812f41 | ||
|
|
e7aeb3feaf | ||
|
|
adf4c9a0ce | ||
|
|
38d1525092 | ||
|
|
56b2c10312 | ||
|
|
db5846c145 | ||
|
|
73dab7e00b | ||
|
|
54c1fcf33d | ||
|
|
604acd8939 | ||
|
|
3d9c287410 | ||
|
|
78dbaf2ed1 | ||
|
|
7852da1506 | ||
|
|
e7a2f171d9 | ||
|
|
dc3f91b121 | ||
|
|
064601ae5e | ||
|
|
2b036c7334 | ||
|
|
6a774e4685 | ||
|
|
83fb898852 | ||
|
|
4317fc36a8 | ||
|
|
57d43786ab | ||
|
|
1069d5dec4 | ||
|
|
d055494706 | ||
|
|
0a6bebf9db | ||
|
|
5b2e1a0aae | ||
|
|
46ddc9b6be | ||
|
|
5cbe633117 | ||
|
|
719ea47a35 | ||
|
|
70eeddabba | ||
|
|
d756225684 | ||
|
|
26de17f2de | ||
|
|
be0d751334 | ||
|
|
4b0bac34dd | ||
|
|
bf8bd9cb1a | ||
|
|
e009b8f4b4 | ||
|
|
47cbaeed23 | ||
|
|
4e29b6752e | ||
|
|
046735f043 | ||
|
|
a9b05fd029 | ||
|
|
5c8e436401 | ||
|
|
4d805da6ac | ||
|
|
085800f6e0 | ||
|
|
1934fc9bd4 | ||
|
|
8c1848b487 | ||
|
|
8edb10fb88 | ||
|
|
8aecc49456 | ||
|
|
b8919c21d8 | ||
|
|
9203b24eb9 | ||
|
|
8584e6da4c | ||
|
|
1d673df1bd | ||
|
|
b3adf71ed7 | ||
|
|
7ba0b6482c | ||
|
|
e99175444f | ||
|
|
d5ed31ca9b | ||
|
|
1c8027b1e6 | ||
|
|
ebac80b5b7 | ||
|
|
4cab6a89a9 | ||
|
|
50a360d314 | ||
|
|
4e96dccd7c | ||
|
|
7755033017 | ||
|
|
aed472af77 | ||
|
|
c528a15e95 | ||
|
|
6dc4a60724 | ||
|
|
f6785c399d | ||
|
|
237f84cde0 | ||
|
|
485ad8e645 | ||
|
|
1582bf43c5 | ||
|
|
a1fa43850b | ||
|
|
5e799b1f81 | ||
|
|
5bc8102864 | ||
|
|
0296812e88 | ||
|
|
d8c846288e | ||
|
|
dd1e9a68d4 | ||
|
|
21860ded90 | ||
|
|
48113f8506 | ||
|
|
db7155666d | ||
|
|
b758014ebc | ||
|
|
18816ae146 | ||
|
|
dc106c5442 | ||
|
|
aa3228be76 | ||
|
|
c2ce72ed94 | ||
|
|
4cd2de0fff | ||
|
|
b318a0703b | ||
|
|
ea67aca955 | ||
|
|
0ab140a071 | ||
|
|
d5eb2432ef | ||
|
|
a6c2d256c6 | ||
|
|
7a8a2757db | ||
|
|
d8d3cafc32 | ||
|
|
604824335c | ||
|
|
9240147874 | ||
|
|
05a6323d2c | ||
|
|
1dd0b7713b | ||
|
|
795f70a0b0 | ||
|
|
5831af0fb6 | ||
|
|
e8e3e43711 | ||
|
|
460b05d37a | ||
|
|
f03405ca47 | ||
|
|
0405ed9e3d | ||
|
|
2eb8f2f84a | ||
|
|
6894d4c0bc | ||
|
|
53c04b7299 | ||
|
|
3bf307abb0 | ||
|
|
4928d29a8e | ||
|
|
8cec9c7b73 | ||
|
|
a6e3352073 | ||
|
|
0eeea37662 | ||
|
|
2a8f55e99e | ||
|
|
db7b0c1785 | ||
|
|
55e64f6ab0 | ||
|
|
6fce7062e5 | ||
|
|
2df8ba19f4 | ||
|
|
e4a3b3b5ba | ||
|
|
0494dc8d32 | ||
|
|
3dd33518c4 | ||
|
|
db8225a078 | ||
|
|
8bc05f6d15 | ||
|
|
00fb7804da | ||
|
|
3091d9c847 | ||
|
|
d1de4d53fe | ||
|
|
c08c2a55e5 | ||
|
|
cddd21d879 | ||
|
|
188e42ee4a | ||
|
|
f606477ae5 | ||
|
|
5250b218c5 | ||
|
|
909247a179 | ||
|
|
e7dea2714e | ||
|
|
dcc2e52c61 | ||
|
|
db17b93156 | ||
|
|
11c5e1cf4c | ||
|
|
cef7ea9f5e | ||
|
|
31d2a15957 | ||
|
|
e622e03d2a | ||
|
|
5b0597ea47 | ||
|
|
5f3ca7fda0 | ||
|
|
3a414b21fa | ||
|
|
e99a906f54 | ||
|
|
fc4b02cee8 | ||
|
|
e01567553e | ||
|
|
bf7b0bf4bf | ||
|
|
ece92a1b7c | ||
|
|
2da5c51e42 | ||
|
|
57228fa208 | ||
|
|
024c62aed4 | ||
|
|
e56f14502e | ||
|
|
82eb1a946e | ||
|
|
85855ecd85 | ||
|
|
cbfd31a576 | ||
|
|
b6f1bb570f | ||
|
|
896036b3c2 | ||
|
|
e51937cee7 | ||
|
|
a47dbf88bb | ||
|
|
f9a868a979 | ||
|
|
56542a02e8 | ||
|
|
2dda9499fa | ||
|
|
f9738cb611 | ||
|
|
741a160913 | ||
|
|
5daf817e7e | ||
|
|
9175bc0e16 | ||
|
|
b7f1fdd9cc | ||
|
|
07f88d21bd | ||
|
|
a7d1a4611f | ||
|
|
c96b840c53 | ||
|
|
70445ab8a3 | ||
|
|
136e6dd389 | ||
|
|
94edef2c3f | ||
|
|
1434e8d6e9 | ||
|
|
54a53b574f | ||
|
|
c9954cf14e | ||
|
|
7ca974f731 | ||
|
|
54771409d6 | ||
|
|
63ae33eca7 | ||
|
|
b485048f6b | ||
|
|
3ed2da9282 | ||
|
|
7aa95debf1 | ||
|
|
f178de2ff8 | ||
|
|
2d9402fd2d | ||
|
|
5188693469 | ||
|
|
68911876b9 | ||
|
|
10c19731b3 | ||
|
|
820b4ea358 | ||
|
|
d8485350e7 | ||
|
|
b4b6186f54 | ||
|
|
8889f6b837 | ||
|
|
3ea353bef3 | ||
|
|
ca746f3b47 | ||
|
|
9f7e81cec2 | ||
|
|
bc3ad59dd5 | ||
|
|
979adcd6e2 | ||
|
|
c5c1294d7d | ||
|
|
0ce91ce5ed | ||
|
|
67e4518132 | ||
|
|
b76cb36c0f | ||
|
|
0636f0049a | ||
|
|
8346ce4cd8 | ||
|
|
e565341e90 | ||
|
|
1b2c0ba02b | ||
|
|
cbbe678f9e | ||
|
|
5efcc7186e | ||
|
|
d188ecae70 | ||
|
|
d71210e942 | ||
|
|
9c20139ae8 | ||
|
|
da19e770a2 | ||
|
|
5e7acb9f3a | ||
|
|
6d379448be | ||
|
|
79763aacf7 | ||
|
|
4b592f7507 | ||
|
|
e7ef9eff4f | ||
|
|
9e2049c463 | ||
|
|
8aa7113480 | ||
|
|
b1b9172f28 | ||
|
|
3a691e0c23 | ||
|
|
a9a308e5e9 | ||
|
|
e7f4fc7107 | ||
|
|
ac60260da2 | ||
|
|
364cf1ec73 | ||
|
|
297c386b16 | ||
|
|
152a3685fa | ||
|
|
bb7464a975 | ||
|
|
9c1237ca05 | ||
|
|
69e0738096 | ||
|
|
cd27184332 | ||
|
|
cadf654fae | ||
|
|
d5892bbb32 | ||
|
|
0b31537bfe | ||
|
|
776a977824 | ||
|
|
20ae72e5fa | ||
|
|
7fc4348f64 | ||
|
|
5ec116021a | ||
|
|
a992333744 | ||
|
|
5cf091b8b2 | ||
|
|
bea4bc6a1a | ||
|
|
9596514c79 | ||
|
|
fefe0df922 | ||
|
|
509bdcb891 | ||
|
|
2fbd53807c | ||
|
|
9498375e75 | ||
|
|
639b264d2d | ||
|
|
c3829485e4 | ||
|
|
88de1b28a2 | ||
|
|
17e0c79fe7 | ||
|
|
ddef80d2cf | ||
|
|
1872337f5f | ||
|
|
6e219f0a4e | ||
|
|
a408c2211b | ||
|
|
8b2dcb6cb0 | ||
|
|
b0fe12f597 | ||
|
|
9a1cc8b9a8 | ||
|
|
cce4d50378 | ||
|
|
e732e62b39 | ||
|
|
728056acdb | ||
|
|
b85d282dfb | ||
|
|
194902798b | ||
|
|
cc276ff232 | ||
|
|
5538fe27e5 | ||
|
|
c0ba3e95f3 | ||
|
|
4ec6f853d8 | ||
|
|
6dcda3595e | ||
|
|
c4a9eb9e44 | ||
|
|
ba57bb1396 | ||
|
|
f94f4a1191 | ||
|
|
469f76e690 | ||
|
|
0098466704 | ||
|
|
48ddfd25d4 | ||
|
|
2f3841d7e6 | ||
|
|
1cde242f06 | ||
|
|
a0b227fdd8 | ||
|
|
36a79d7cbe | ||
|
|
2c491bc905 | ||
|
|
a25c405eae | ||
|
|
e666c60e7d | ||
|
|
6a45e68c73 | ||
|
|
59b313352b | ||
|
|
9e04f9ba80 | ||
|
|
cf5838505f | ||
|
|
23469c00de | ||
|
|
66083d6531 | ||
|
|
1c3748e923 | ||
|
|
88bf01fe6f | ||
|
|
a969a8f99c | ||
|
|
ef0e34a278 | ||
|
|
50eb45991d | ||
|
|
ffa405dad9 | ||
|
|
1f966eb6c3 | ||
|
|
b503540075 | ||
|
|
2be305d39e | ||
|
|
f6ee966e17 | ||
|
|
246315c723 | ||
|
|
be8f16a8e6 | ||
|
|
32614d3539 | ||
|
|
aab978c7ea | ||
|
|
d4b48fae6f | ||
|
|
0433bd8560 | ||
|
|
71eb0fedd9 | ||
|
|
9056ae72d3 | ||
|
|
430a5359ac | ||
|
|
5468bc8447 | ||
|
|
059005a4a7 | ||
|
|
3ca39ab3f1 | ||
|
|
f8a6e2e19f | ||
|
|
1f5c2095a5 | ||
|
|
afaaba6b3c | ||
|
|
5ada2d4b6f | ||
|
|
dd15b9234f | ||
|
|
c85f976ed6 | ||
|
|
b22832ba54 | ||
|
|
977f17a893 | ||
|
|
60621a300c | ||
|
|
fac3fc67b6 | ||
|
|
d03d145be4 | ||
|
|
8e3da75c3c | ||
|
|
1083d7e0ef | ||
|
|
cdaa4b4e99 | ||
|
|
c9dc2eaad4 | ||
|
|
295fcb53b0 | ||
|
|
389c35e08e | ||
|
|
8095d6c48c | ||
|
|
6f2e192947 | ||
|
|
0b9d8c7b47 | ||
|
|
1ecea32933 | ||
|
|
ceae4470f5 | ||
|
|
237455f4b7 | ||
|
|
3d25f8ee79 | ||
|
|
86572462e6 | ||
|
|
245eaa1fd9 | ||
|
|
003aa6a4eb | ||
|
|
f9d205b869 | ||
|
|
e08afcb963 | ||
|
|
e7b712660e | ||
|
|
3750123e43 | ||
|
|
b20f39d09f | ||
|
|
c35f762826 | ||
|
|
7eda762c28 | ||
|
|
0460769eea | ||
|
|
d3939c785d | ||
|
|
66386d6eec | ||
|
|
9e8dafc4ca | ||
|
|
36a698fee4 | ||
|
|
aab764a6e5 | ||
|
|
11f30bc28d | ||
|
|
46b5595c3f | ||
|
|
c380f1f399 | ||
|
|
184882e916 | ||
|
|
a9963bcdb3 | ||
|
|
e0c0da7dff | ||
|
|
6c9df4574c | ||
|
|
034c83f996 | ||
|
|
2b582b169b | ||
|
|
cfa8df0575 | ||
|
|
c34f2941aa | ||
|
|
555b397067 | ||
|
|
38f59e640c | ||
|
|
65ce7dabe3 | ||
|
|
4d7d3ea937 | ||
|
|
15b6593143 | ||
|
|
af1e7b346e | ||
|
|
7a2f572eaa | ||
|
|
4bb3ed0d85 | ||
|
|
5fe0820e13 | ||
|
|
28a4101d4d | ||
|
|
cc22edcce3 | ||
|
|
2424d2a082 | ||
|
|
b1ccb70277 | ||
|
|
c641cc6394 | ||
|
|
9a6568f5e8 | ||
|
|
3627b33eec | ||
|
|
702eb95b84 | ||
|
|
03f191f47d | ||
|
|
813a4b0200 | ||
|
|
c24950b261 | ||
|
|
806abb1985 | ||
|
|
a4591a5eaa | ||
|
|
018737eb15 | ||
|
|
3e5bd4e13b | ||
|
|
98ec8b9910 | ||
|
|
d2a966f363 | ||
|
|
8a7cc9259c | ||
|
|
382fc710e5 | ||
|
|
be4229867a | ||
|
|
6b05022530 | ||
|
|
08a3828cc9 | ||
|
|
d5efedf51b | ||
|
|
8394a96fa8 | ||
|
|
4f7e869509 | ||
|
|
7aac61859f | ||
|
|
3ba967bdc1 | ||
|
|
9fb4e677a6 | ||
|
|
1ffb5aa6fe | ||
|
|
0100cd2f36 | ||
|
|
d6b486524c | ||
|
|
f80394fc02 | ||
|
|
e750c598be | ||
|
|
26191dd274 | ||
|
|
12171f6cd9 | ||
|
|
457276fa5d | ||
|
|
7ba21ac4fd | ||
|
|
e2b011590d | ||
|
|
ef6f411b70 | ||
|
|
2c48161595 | ||
|
|
ca3e0d2ba9 | ||
|
|
922e234fe9 | ||
|
|
b9cfd2fae5 | ||
|
|
d8bc84adb1 | ||
|
|
ce3511f7ea | ||
|
|
a8e1bd1538 | ||
|
|
0876c8c2bf | ||
|
|
0554ecae5c | ||
|
|
cfbc8a23f7 | ||
|
|
5e71d9578f | ||
|
|
8b19f82c0b | ||
|
|
794dbacea3 | ||
|
|
3a4b6cf6b6 | ||
|
|
c0c9c51e43 | ||
|
|
e788ee5faf | ||
|
|
e17405d80a | ||
|
|
de52eebe7a | ||
|
|
d7069a2a66 | ||
|
|
7faa19b297 | ||
|
|
5e6ed2dc9f | ||
|
|
adebc36bc7 | ||
|
|
165bebda3e | ||
|
|
0f54e5fe46 | ||
|
|
14c046108e | ||
|
|
b5a8850d65 | ||
|
|
3f51bb6e1d | ||
|
|
bf4100c024 | ||
|
|
aab195a6eb | ||
|
|
2400d146ce | ||
|
|
9a9b5ce61e | ||
|
|
6b473c6edc | ||
|
|
9d8f31a0cb | ||
|
|
5947769812 | ||
|
|
52673f5249 | ||
|
|
f44de434c2 | ||
|
|
cbb27a5661 | ||
|
|
48eaccc612 | ||
|
|
5499136677 | ||
|
|
57b66a9be9 | ||
|
|
746f419e80 | ||
|
|
5d1a138c5c | ||
|
|
e781870da3 | ||
|
|
e3f30fece9 | ||
|
|
7b2536eb0d | ||
|
|
299382b907 | ||
|
|
fce64f8f12 | ||
|
|
f8bf11d574 | ||
|
|
fdfe0cae87 | ||
|
|
66664660d7 | ||
|
|
760ac98ab6 | ||
|
|
2bd5d88dbf | ||
|
|
5f78a36899 | ||
|
|
b897b9427f | ||
|
|
c33b1004d1 | ||
|
|
19e8977fff | ||
|
|
c097d650dc | ||
|
|
b7af32bee3 | ||
|
|
d2422b03be | ||
|
|
97d2085735 | ||
|
|
e307df79a1 | ||
|
|
324fe06a06 | ||
|
|
fe15371047 | ||
|
|
fbb7196100 | ||
|
|
8c9a9c9d12 | ||
|
|
6f8ea87c46 | ||
|
|
3d84157325 | ||
|
|
9abf8ddf91 | ||
|
|
f289d5d9e7 | ||
|
|
821c03a389 | ||
|
|
c37a473287 | ||
|
|
3eebedc4c3 | ||
|
|
5eb99b7d2f | ||
|
|
3534706a59 | ||
|
|
717a8a5cdb | ||
|
|
586d8fdf21 | ||
|
|
f4016c2e1c | ||
|
|
2bb08d7638 | ||
|
|
155cc56632 | ||
|
|
4a4032f3b8 | ||
|
|
cd5aa8f074 | ||
|
|
c2b26f6c15 | ||
|
|
f25ca2ac80 | ||
|
|
303c74f4c9 | ||
|
|
59d4d833f1 | ||
|
|
562acd6e2c | ||
|
|
c3d76669ca | ||
|
|
14d8d14832 | ||
|
|
cdc04ba413 | ||
|
|
ab91525e7a | ||
|
|
0a4b3487ea | ||
|
|
0061055e73 | ||
|
|
a16c4015ba | ||
|
|
0173c29630 | ||
|
|
26a734a538 | ||
|
|
04e7dc1270 | ||
|
|
1cdc11dae2 | ||
|
|
1cb75c4471 | ||
|
|
b6efc9f583 | ||
|
|
01868e46fe | ||
|
|
313cce23db | ||
|
|
9aca1f41f3 | ||
|
|
81c7445744 | ||
|
|
d54daa19a0 | ||
|
|
0c58a42b08 | ||
|
|
68cbf31c8b | ||
|
|
d518222340 | ||
|
|
7a35a43bd4 | ||
|
|
cb52e82a60 | ||
|
|
1a43bc8abf | ||
|
|
e88c39b090 | ||
|
|
a1f5e6ba43 | ||
|
|
d0a0aa7a65 | ||
|
|
8cf956e669 | ||
|
|
3bbb23b1bc | ||
|
|
a582b5996c | ||
|
|
4cd10c34e2 | ||
|
|
3ec1dbf51c | ||
|
|
71deb8925e | ||
|
|
abb562d1ab | ||
|
|
a495a6bfbc | ||
|
|
e86b17be2d | ||
|
|
e62f805bcd | ||
|
|
6f8ae718d1 | ||
|
|
1dcfa9e0ee | ||
|
|
7f0664ff82 | ||
|
|
03b3e60e23 | ||
|
|
72bde5234a | ||
|
|
1e1f5e8193 | ||
|
|
6c01b6da9b | ||
|
|
756aac1f9a | ||
|
|
c0ac428179 | ||
|
|
7549b471c3 | ||
|
|
0b265320a9 | ||
|
|
6033a76870 | ||
|
|
3708d55ef9 | ||
|
|
9996cf6157 | ||
|
|
3e78b7c262 | ||
|
|
65e012c540 | ||
|
|
2a88f7d7c4 | ||
|
|
dca9501de7 | ||
|
|
8ed6b549ee | ||
|
|
1a741b97d2 | ||
|
|
33809f56c5 | ||
|
|
67ee544231 | ||
|
|
94f61ce307 | ||
|
|
b57f7cdc79 | ||
|
|
c901a7136f | ||
|
|
243db9a3a8 | ||
|
|
a5ef61ac82 | ||
|
|
9e272aeef0 | ||
|
|
5c45979783 | ||
|
|
02f214d8a7 | ||
|
|
daac25c343 | ||
|
|
768f1b5710 | ||
|
|
5b4b9fd169 | ||
|
|
7dea357f4c | ||
|
|
9ef10b1663 | ||
|
|
d2004e88f9 | ||
|
|
ef27cc54dd | ||
|
|
19390eaec3 | ||
|
|
dff6171605 | ||
|
|
4fe84efafd | ||
|
|
ed4997168b | ||
|
|
b92de9beb5 | ||
|
|
7f50b2ba7b | ||
|
|
c35bc71334 | ||
|
|
413a8111c0 | ||
|
|
5be31898f1 | ||
|
|
44faf3e169 | ||
|
|
937a60c8f9 | ||
|
|
f7626699da | ||
|
|
ad97c72821 | ||
|
|
b7ce7b7dab | ||
|
|
b73f4dd8e4 | ||
|
|
a4bf92dae4 | ||
|
|
1e745ba48b | ||
|
|
f8273e977e | ||
|
|
605843b527 | ||
|
|
71d2bd83aa | ||
|
|
a12704c6a3 | ||
|
|
43271f290e | ||
|
|
7533b475be | ||
|
|
1b89e5c973 | ||
|
|
8ba127d4c5 | ||
|
|
bb8ea493d6 | ||
|
|
02cffa9a71 | ||
|
|
76fc30e460 | ||
|
|
e8ec81bf04 | ||
|
|
9fba54ad5d | ||
|
|
ccd98c3c3d | ||
|
|
2539e41e59 | ||
|
|
83312fbb74 | ||
|
|
6134162f1c | ||
|
|
fb713226a0 | ||
|
|
3ac46f5fa7 | ||
|
|
d5c507ca6b | ||
|
|
858bb15a6b | ||
|
|
faee255730 | ||
|
|
eb5b1312bb | ||
|
|
5445b4f97a | ||
|
|
02ead94848 | ||
|
|
6a4f76a219 | ||
|
|
1252b0bde2 | ||
|
|
a40fbf0da1 | ||
|
|
468f52a4f6 | ||
|
|
3f1fb9a66e | ||
|
|
c181891549 | ||
|
|
f84f4aa058 | ||
|
|
5d5c3e2a48 | ||
|
|
5b8b88e05a | ||
|
|
0287e21c01 | ||
|
|
7d2f2bd610 | ||
|
|
d56393b134 | ||
|
|
1f7ed035d3 | ||
|
|
8430328043 | ||
|
|
f311852e9b | ||
|
|
ac0a32e690 | ||
|
|
88482a2431 | ||
|
|
efbd339dc8 | ||
|
|
ff28ce8d65 | ||
|
|
cb33470673 | ||
|
|
e6389d62dc | ||
|
|
2766f17cb9 | ||
|
|
70c36716c9 | ||
|
|
48702b1ed9 | ||
|
|
16216b2ed0 | ||
|
|
3e22553d7e | ||
|
|
4744839a08 | ||
|
|
cb0c13a1a1 | ||
|
|
f0497a2721 | ||
|
|
77d018dbc8 | ||
|
|
4be8b50360 | ||
|
|
2581935b36 | ||
|
|
a7cf09883e | ||
|
|
1254a7bbe2 | ||
|
|
fb5ec1d1f5 | ||
|
|
5bcb350d89 | ||
|
|
81bc6b49f8 | ||
|
|
9019a1eb23 | ||
|
|
f3780998ed | ||
|
|
27090c541f | ||
|
|
ef73469700 | ||
|
|
2d12a82a54 | ||
|
|
c5d9dc4732 | ||
|
|
84ec70e707 | ||
|
|
b7f5d7e415 | ||
|
|
8df7a52cf7 | ||
|
|
9bb9292a41 | ||
|
|
438c499718 | ||
|
|
ff81d9461a | ||
|
|
f4f85aa1fd | ||
|
|
56f2f0b727 | ||
|
|
19f325aa09 | ||
|
|
1d5a63c180 | ||
|
|
d7da5153f3 | ||
|
|
c67f010302 | ||
|
|
90a10b3508 | ||
|
|
a09f7d274f | ||
|
|
daa9466b7a | ||
|
|
efb252206b | ||
|
|
ffb847bbc0 | ||
|
|
44b2392a10 | ||
|
|
855540b5c5 | ||
|
|
a7b9b0da42 | ||
|
|
5f8eac9dc8 | ||
|
|
b0ea103c61 | ||
|
|
65781e6080 | ||
|
|
fc0149cdbc | ||
|
|
3946c076fe | ||
|
|
b5b6d3f85c | ||
|
|
10f09dc15d | ||
|
|
f50d23a0d4 | ||
|
|
cb9f972d13 | ||
|
|
53fd33604d | ||
|
|
c8e3935648 | ||
|
|
8f9c8ee293 | ||
|
|
767fe92de5 | ||
|
|
435b9cd1bb | ||
|
|
afc7c2b449 | ||
|
|
e0a7c7e935 | ||
|
|
b0415370f8 | ||
|
|
b7ff2fe3e3 | ||
|
|
7978f5ebfe | ||
|
|
b663110288 | ||
|
|
3ef9e3bc69 | ||
|
|
a032bd28ad | ||
|
|
834a524a67 | ||
|
|
e3460bea09 | ||
|
|
31041f2ade | ||
|
|
3320272673 | ||
|
|
131959e388 | ||
|
|
d23835a6c2 | ||
|
|
e17632e0d5 | ||
|
|
d57a3b101b | ||
|
|
c2289c047b | ||
|
|
4ade726a07 | ||
|
|
856a45a775 | ||
|
|
f64ccbab7e | ||
|
|
8a44c8fce1 | ||
|
|
2a70dde016 | ||
|
|
f1a5fb6b62 | ||
|
|
04bb15a108 | ||
|
|
9b358a1b39 | ||
|
|
86ad4aabf3 | ||
|
|
36c097744c | ||
|
|
e7cd445491 | ||
|
|
9b66d74382 | ||
|
|
e3752aefed | ||
|
|
d8ff809092 | ||
|
|
a8f5bf8baf | ||
|
|
3a3605b812 | ||
|
|
f1c635d103 | ||
|
|
15cce79040 | ||
|
|
fef681be7c | ||
|
|
e379a5a03e | ||
|
|
f2b4911f60 | ||
|
|
ff93de6e61 | ||
|
|
29adc28d80 | ||
|
|
118937aa99 | ||
|
|
6ec4c65f04 | ||
|
|
fefb40bda2 | ||
|
|
c5938f7d31 | ||
|
|
e748b74c67 | ||
|
|
a957d58939 | ||
|
|
37a9a52544 | ||
|
|
566d70a6d1 | ||
|
|
7b7157f491 | ||
|
|
ea8791697e | ||
|
|
dd9f7bba5d | ||
|
|
8051cd4194 | ||
|
|
b4a7fa1ad9 | ||
|
|
e460bd9a69 | ||
|
|
5a3082275e | ||
|
|
bdf20355b6 | ||
|
|
21ea923520 | ||
|
|
484fff444f | ||
|
|
f63d0abbc1 | ||
|
|
5a05898ec4 | ||
|
|
b9ee7cc30a | ||
|
|
03ee96cdff | ||
|
|
be2598bc4c | ||
|
|
01f5fe6eb1 | ||
|
|
32f9cbb11d | ||
|
|
67e99c799c | ||
|
|
da5284c6b8 | ||
|
|
c2fa79347e | ||
|
|
953a7ff066 | ||
|
|
84cabd6a1e | ||
|
|
e1a6b7e249 | ||
|
|
72b342912e | ||
|
|
07f52c463e | ||
|
|
064f0216b4 | ||
|
|
70a4d113b3 | ||
|
|
2001d6b6ec | ||
|
|
b278cbb32e | ||
|
|
7ec9af8200 | ||
|
|
71b0c35653 | ||
|
|
4032df3115 | ||
|
|
6eadc29ca0 | ||
|
|
c6f7a39d22 | ||
|
|
73099edae3 | ||
|
|
f53646764c | ||
|
|
7b42fea0f5 | ||
|
|
df1e9732d0 | ||
|
|
822ba4432f | ||
|
|
8e6c6acf18 | ||
|
|
83b13f6a3f | ||
|
|
aceb3f3425 | ||
|
|
37f2ec2f9f | ||
|
|
4d1e822de7 | ||
|
|
b8276fd8e3 | ||
|
|
d319ebc0a8 | ||
|
|
5f32d9347d | ||
|
|
ba136fe42d | ||
|
|
e4090b1475 | ||
|
|
b7d2ecbf1a | ||
|
|
f77f846c8d | ||
|
|
23b34aeb92 | ||
|
|
59c887129d | ||
|
|
bd7cd9245a | ||
|
|
53c7cf116c | ||
|
|
95b7842e31 | ||
|
|
0b953ccc40 | ||
|
|
41c4eabcaa | ||
|
|
0a33a3a71a | ||
|
|
d6b470cd07 | ||
|
|
d1cb627582 | ||
|
|
1d99158562 | ||
|
|
05c32c7a62 | ||
|
|
ea4d32b4ad | ||
|
|
bb9e260793 | ||
|
|
536cb6febd | ||
|
|
258fe8bad0 | ||
|
|
74772a1f61 | ||
|
|
bdaa5f20a1 | ||
|
|
19293601b3 | ||
|
|
f2bcfa5275 | ||
|
|
6265027222 | ||
|
|
36ff4dcd11 | ||
|
|
35a53ef1d7 | ||
|
|
507c5eb7ca | ||
|
|
169670a58b | ||
|
|
fbb5dced97 | ||
|
|
aa54a386f3 | ||
|
|
6b8c58e3b5 | ||
|
|
67f4797e09 | ||
|
|
7335ae548c | ||
|
|
0b1a5bc3c1 | ||
|
|
e9c54bb5e4 | ||
|
|
4294038271 | ||
|
|
408eab13f0 | ||
|
|
ee0bd9ee76 | ||
|
|
263a25fb87 | ||
|
|
fa10ce28d2 | ||
|
|
039f665af1 | ||
|
|
304fa05094 | ||
|
|
89ad14b82f | ||
|
|
73785af730 | ||
|
|
d2c3e50a3f | ||
|
|
2fbe7ab6ce | ||
|
|
164799e4c4 | ||
|
|
4f57269518 | ||
|
|
92c9311a4c | ||
|
|
ca6fd89700 | ||
|
|
80b100f135 | ||
|
|
8e12f11089 | ||
|
|
f4324e8890 | ||
|
|
fda34fea46 | ||
|
|
0770150455 | ||
|
|
d79a8fc87b | ||
|
|
8e1bbfe938 | ||
|
|
3469d65f95 | ||
|
|
486536f92d | ||
|
|
70717cb6c8 | ||
|
|
94ebcdeb6b | ||
|
|
152238e67f | ||
|
|
eef51e0bd0 | ||
|
|
91df8446b0 | ||
|
|
ffb55f482a | ||
|
|
b2c5a84964 | ||
|
|
0be43cf1c2 | ||
|
|
f5923860fa | ||
|
|
adc2921f38 | ||
|
|
ca630a106e | ||
|
|
cbbc42d564 | ||
|
|
0054e6a378 | ||
|
|
76e30150b9 | ||
|
|
cd197a3807 | ||
|
|
b9673df961 | ||
|
|
37c8ea54eb | ||
|
|
e616b40c6f | ||
|
|
26109ca8f9 | ||
|
|
46e57d4f1c | ||
|
|
7743843a27 | ||
|
|
c84e145557 | ||
|
|
e767392b44 | ||
|
|
457177905d | ||
|
|
de74443d76 | ||
|
|
f3e7340118 | ||
|
|
efe3dd77fa | ||
|
|
7c690b9de1 | ||
|
|
5ce8770dc3 | ||
|
|
e9ddd6b8f8 | ||
|
|
f94f458922 | ||
|
|
89ef06fd3f | ||
|
|
ccd135b2a6 | ||
|
|
80eb0851d9 | ||
|
|
b84f470fca | ||
|
|
5caeccc007 | ||
|
|
96a4e16a4b | ||
|
|
477c657f60 | ||
|
|
68ad5411c9 | ||
|
|
cc50e620c0 | ||
|
|
8646abb18b | ||
|
|
2fbf6b732e | ||
|
|
93416e40a4 | ||
|
|
d2210414bc | ||
|
|
e6e9a21597 | ||
|
|
e14be5c8c2 | ||
|
|
f9b3561ca8 | ||
|
|
95083e846b | ||
|
|
ce415fb65c | ||
|
|
f479ea4bcf | ||
|
|
1a6c00ca8b | ||
|
|
58033d3cbc | ||
|
|
4c23ab029a | ||
|
|
0846f8a963 | ||
|
|
65a1aae629 | ||
|
|
caef97ad36 | ||
|
|
761439cc8d | ||
|
|
b847c53395 | ||
|
|
aca3e8f6c4 | ||
|
|
7122a7c174 | ||
|
|
769a7b89d2 | ||
|
|
d2b13f515d | ||
|
|
ef601d3345 | ||
|
|
d9e5601e10 | ||
|
|
c385133c84 | ||
|
|
b91a670c05 | ||
|
|
c90c8e0f4b | ||
|
|
0a8cd6d03d | ||
|
|
af89351432 | ||
|
|
fb81754880 | ||
|
|
dc5bfc1c41 | ||
|
|
98c740f204 | ||
|
|
255742db26 | ||
|
|
af4ceb0658 | ||
|
|
08d72b12ab | ||
|
|
5fb4badb7c | ||
|
|
4650636e5a | ||
|
|
2c65da3397 | ||
|
|
abc1d185b7 | ||
|
|
124eba4371 | ||
|
|
a673496ed3 | ||
|
|
af2a49afa7 | ||
|
|
b151796e0e | ||
|
|
828b2c9bc0 | ||
|
|
be8b838334 | ||
|
|
73fedf453c | ||
|
|
e03de192c8 | ||
|
|
725cdc2d69 | ||
|
|
048c57cf0c | ||
|
|
12dcbfbc79 | ||
|
|
32be05fa6c | ||
|
|
ae62b67554 | ||
|
|
29908533cd | ||
|
|
9c4f22d85b | ||
|
|
7f64668e55 | ||
|
|
0208942b84 | ||
|
|
783e86990c | ||
|
|
cdefc0e384 | ||
|
|
1c9f996248 | ||
|
|
c9715c5b0b | ||
|
|
dd47123bde | ||
|
|
594dc64a43 | ||
|
|
1b69994ffa | ||
|
|
3de21156b5 | ||
|
|
ce2c6ab49e | ||
|
|
d19c5a4a4a | ||
|
|
8945fe4857 | ||
|
|
464919072d | ||
|
|
f8c2087d74 | ||
|
|
7adc0e24ab | ||
|
|
ba65f29a72 | ||
|
|
76eef6fe59 | ||
|
|
1d1947c51a | ||
|
|
af4ac8fb5f | ||
|
|
adaf5cd69c | ||
|
|
516f5a40d0 | ||
|
|
3b7887a041 | ||
|
|
fe38f59bbb | ||
|
|
cd93aba002 | ||
|
|
2bcabce1d6 | ||
|
|
6ed9a62501 | ||
|
|
b987c025db | ||
|
|
27d8d100c5 | ||
|
|
701230b49c | ||
|
|
726d8248c5 | ||
|
|
07a2c5a81d | ||
|
|
081ae32d35 | ||
|
|
a7f02b3964 | ||
|
|
e116548b50 | ||
|
|
3190814265 | ||
|
|
eeea2b4de4 | ||
|
|
21f6174846 | ||
|
|
ed4c6b7c92 | ||
|
|
89be317a00 | ||
|
|
1ad4597d7a | ||
|
|
c65b659538 | ||
|
|
3c23163a29 | ||
|
|
c3900ee4f3 | ||
|
|
9c5da9e42c | ||
|
|
efa970c6a5 | ||
|
|
179f04739d | ||
|
|
b2f513caae | ||
|
|
9c1e74b0c0 | ||
|
|
e53af58d4a | ||
|
|
d9cb2ce6c7 | ||
|
|
a967f2b037 | ||
|
|
db5a7578c9 | ||
|
|
15086833a3 | ||
|
|
785729abdf | ||
|
|
32f407340f | ||
|
|
2830b35aa6 | ||
|
|
fb38f6adea | ||
|
|
a1e714dce7 | ||
|
|
3710ea903e | ||
|
|
72a9b6b7fe | ||
|
|
0d3fab40e5 | ||
|
|
3a30f1dc71 | ||
|
|
95abf3dca3 | ||
|
|
4e4d554ea4 | ||
|
|
9642780bb8 | ||
|
|
73bc656e63 | ||
|
|
b8b235df09 | ||
|
|
7b23aece00 | ||
|
|
531af998fb | ||
|
|
c7bdaf6632 | ||
|
|
92c7792e95 | ||
|
|
c9e0a6c533 | ||
|
|
6331267df6 | ||
|
|
1e81966b89 | ||
|
|
b785b9d219 | ||
|
|
85da7163a7 | ||
|
|
f3f8bee83b | ||
|
|
8802d5033f | ||
|
|
3d39564605 | ||
|
|
7843f51110 | ||
|
|
8bfdc98ef4 | ||
|
|
6673c89791 | ||
|
|
a8a30ae3b9 | ||
|
|
15af410e6f | ||
|
|
9e5cbf330f | ||
|
|
2fa9334090 | ||
|
|
fcdf5d377e | ||
|
|
756a284048 | ||
|
|
32e2b584b9 | ||
|
|
add52b4d57 | ||
|
|
a4d2cb3d12 | ||
|
|
72fbb3f63e | ||
|
|
c62290accb | ||
|
|
8ad40c5d66 | ||
|
|
cd5a721c23 | ||
|
|
643844c01d | ||
|
|
1a3c9ac5ef | ||
|
|
c84f080fc8 | ||
|
|
5fcdbfdd9e | ||
|
|
77dca2ddb2 | ||
|
|
d8fc691625 | ||
|
|
96fa4af939 | ||
|
|
2334793554 | ||
|
|
20e445b4be | ||
|
|
051263117d | ||
|
|
085db93fc8 | ||
|
|
8fe6925414 | ||
|
|
57ad7e62d2 | ||
|
|
6736e91ce0 | ||
|
|
4cbdb7897d | ||
|
|
d57d0ceb0d | ||
|
|
03608103b8 | ||
|
|
9c58d42a3c | ||
|
|
675d171104 | ||
|
|
bf3e605d3b | ||
|
|
a56ad597d4 | ||
|
|
cc5ffafd7c | ||
|
|
b101bb0001 | ||
|
|
405af67f45 | ||
|
|
f772cbee51 | ||
|
|
72d93b8723 | ||
|
|
7f78870295 | ||
|
|
706b9c55c2 | ||
|
|
48ae0d003d | ||
|
|
51c5933b76 | ||
|
|
0204d09a89 | ||
|
|
465c6b9ed6 | ||
|
|
39847c4688 | ||
|
|
7721c6e3da | ||
|
|
648ed00ce2 | ||
|
|
87c9358813 | ||
|
|
64b968b262 | ||
|
|
c0fbf4bf55 | ||
|
|
900e533b4b | ||
|
|
01818582cf | ||
|
|
9a0620f140 | ||
|
|
0216925e05 | ||
|
|
32b24a98ca | ||
|
|
93d7a4938a | ||
|
|
56265b78ec | ||
|
|
6ee76aa6f7 | ||
|
|
32d6aefe00 | ||
|
|
84795863e5 | ||
|
|
9deb3e433c | ||
|
|
92a5b14347 | ||
|
|
891a330955 | ||
|
|
3cee90fe8b | ||
|
|
2bb58bac2e | ||
|
|
9dc1897b35 | ||
|
|
7a7da24df5 | ||
|
|
46f7250f08 | ||
|
|
58bfe23e5a | ||
|
|
ccb914ea83 | ||
|
|
10fe67f4a6 | ||
|
|
a34247ebf4 | ||
|
|
53e96b02c0 | ||
|
|
7c022d6061 | ||
|
|
14e5b46687 | ||
|
|
0243c61ea1 | ||
|
|
d73d4e9d48 | ||
|
|
3d60d9e3c5 | ||
|
|
329b708aaf | ||
|
|
59e0367dd4 | ||
|
|
56c85813ee | ||
|
|
a6bb2604f6 | ||
|
|
b2c71c099f | ||
|
|
102eca7d65 | ||
|
|
55a1d54b8e | ||
|
|
0c313807ff | ||
|
|
d5e685aaf2 | ||
|
|
214fc0419d | ||
|
|
1e24b889dd | ||
|
|
08dd79fafd | ||
|
|
988e2c3fdf | ||
|
|
92dc20850d | ||
|
|
fa9c366076 | ||
|
|
08ab36a5d9 | ||
|
|
c1c04b489c | ||
|
|
0caa321fe5 | ||
|
|
3acaf773b8 | ||
|
|
5080746fa0 | ||
|
|
66c95af093 | ||
|
|
9241816a71 | ||
|
|
07e1f0e802 | ||
|
|
340f8f1f17 | ||
|
|
0316b7ff9a | ||
|
|
7416d2aaf1 | ||
|
|
cb61342e58 | ||
|
|
d99de40b2b | ||
|
|
533675416c | ||
|
|
8baceee06c | ||
|
|
f7bf5c33bc | ||
|
|
f8445030c7 | ||
|
|
1d60131df7 | ||
|
|
539b6410fa | ||
|
|
75f067d5c9 | ||
|
|
518e9b7513 | ||
|
|
0314bb4d38 | ||
|
|
ddfe004204 | ||
|
|
07375e7a39 | ||
|
|
44b69f3d3e | ||
|
|
bca4cf8584 | ||
|
|
4f3f503953 | ||
|
|
1df635a164 | ||
|
|
f3ae5789be | ||
|
|
cf7cd21474 | ||
|
|
0f8fbcfcc1 | ||
|
|
a1f9109392 | ||
|
|
c648be6410 | ||
|
|
6fa0b668ba | ||
|
|
1925b24512 | ||
|
|
1101b4075a | ||
|
|
edb144bd1d | ||
|
|
bcefad1a97 | ||
|
|
0419f8bee9 | ||
|
|
a67fe755cd | ||
|
|
f012f664d2 | ||
|
|
744563a150 | ||
|
|
389074d1e9 | ||
|
|
93778eccbb | ||
|
|
f46d8e8a10 | ||
|
|
f5bfab139c | ||
|
|
df20f918ba | ||
|
|
b8fc1f634e | ||
|
|
ae9dadb5d8 | ||
|
|
d31c062693 | ||
|
|
544928a039 | ||
|
|
14276b3cf8 | ||
|
|
07e7eeedd1 | ||
|
|
125a10bb44 | ||
|
|
9b8e5c8719 | ||
|
|
a803507d67 | ||
|
|
cb5efad026 | ||
|
|
26922a1578 | ||
|
|
90493b6571 | ||
|
|
2dee921cd5 | ||
|
|
433c7c3f99 | ||
|
|
fef461fd13 | ||
|
|
1f56645b69 | ||
|
|
69ca6cd5b2 | ||
|
|
8805e3fb27 | ||
|
|
64d8397ea5 | ||
|
|
4d4496fc4d | ||
|
|
af67342969 | ||
|
|
d9cbd52ea8 | ||
|
|
8b25d44bcf | ||
|
|
3d6733bed8 | ||
|
|
c3f3db518b | ||
|
|
385ec62e53 | ||
|
|
881524831f | ||
|
|
376be8b990 | ||
|
|
96ddbf2a8b | ||
|
|
c2ee420917 | ||
|
|
74a1ba0d1e | ||
|
|
0dc05a39e6 | ||
|
|
72fe406f64 | ||
|
|
90ac174260 | ||
|
|
b555e02220 | ||
|
|
507c94c24c | ||
|
|
2699fa8cf9 | ||
|
|
513002416c | ||
|
|
22530cd77e | ||
|
|
81521b98fd | ||
|
|
73c2feee97 | ||
|
|
d4212d390d | ||
|
|
2b8a55f396 | ||
|
|
f253da09ec | ||
|
|
e232abdab2 | ||
|
|
fae40e0bdf |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* text=auto
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,6 +11,7 @@
|
|||||||
/bin-release
|
/bin-release
|
||||||
/indra/viewer-*
|
/indra/viewer-*
|
||||||
/indra/newview/vivox-runtime/
|
/indra/newview/vivox-runtime/
|
||||||
|
/indra/newview/dbghelp.dll
|
||||||
/libraries/
|
/libraries/
|
||||||
/lib/
|
/lib/
|
||||||
*.pyc
|
*.pyc
|
||||||
@@ -22,3 +23,4 @@
|
|||||||
/LICENSES/
|
/LICENSES/
|
||||||
/edited-files.txt
|
/edited-files.txt
|
||||||
qtcreator-build/
|
qtcreator-build/
|
||||||
|
/.pc
|
||||||
|
|||||||
114
LICENSES/FLOSS-exception.txt
Normal file
114
LICENSES/FLOSS-exception.txt
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
Linden Research, Inc. ("Linden Lab") Viewer FLOSS License Exception v0.5
|
||||||
|
|
||||||
|
The Linden Lab Exception for Free/Libre and Open Source Software-only
|
||||||
|
Applications Using Linden Lab Viewer Software (the "FLOSS Exception").
|
||||||
|
|
||||||
|
Exception Intent
|
||||||
|
|
||||||
|
Linden Lab is releasing the source code for certain software that
|
||||||
|
enables users to view or otherwise access the Second Life virtual
|
||||||
|
world environment (the "Viewer Software"), under version 2 of the GNU
|
||||||
|
General Public License (the "GPL"). The creation or distribution of
|
||||||
|
works based on the Program (as defined under the GPL) of the Viewer
|
||||||
|
Software may require the use of certain Free/Libre and Open Source
|
||||||
|
Software ("FLOSS") works that are subject to license agreements not
|
||||||
|
compatible with re-licensing under the GPL. Because we want to allow
|
||||||
|
the Viewer Software to be distributed with these FLOSS works, this
|
||||||
|
FLOSS Exception following exception applies subject to the terms and
|
||||||
|
conditions below.
|
||||||
|
|
||||||
|
Legal Terms and Conditions
|
||||||
|
|
||||||
|
As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
the GPL:
|
||||||
|
|
||||||
|
You are free to distribute a work based on the Program that is formed
|
||||||
|
entirely from the Viewer Software (and any modifications thereof) and
|
||||||
|
one or more works that are independent and separate works not derived
|
||||||
|
from the Viewer Software, and are licensed under one or more of the
|
||||||
|
licenses listed below in section 1 (each, a "FLOSS Work") , as long
|
||||||
|
as:
|
||||||
|
|
||||||
|
A. You obey the GPL in all respects for the Viewer Software and any
|
||||||
|
work based on the Program, except for the FLOSS Works, for which
|
||||||
|
you must comply with B below,
|
||||||
|
|
||||||
|
B. all FLOSS Works,
|
||||||
|
|
||||||
|
i. are distributed subject to one of the FLOSS licenses
|
||||||
|
listed below, and
|
||||||
|
|
||||||
|
ii. the object code or executable form of the FLOSS Works are
|
||||||
|
accompanied by the complete corresponding
|
||||||
|
machine-readable source code for those FLOSS Works on the
|
||||||
|
same medium and under the same FLOSS license as the
|
||||||
|
corresponding object code or executable forms thereof,
|
||||||
|
and
|
||||||
|
|
||||||
|
C. any works that are aggregated with the Viewer Software or a work
|
||||||
|
based on the Program on a volume of a storage or distribution
|
||||||
|
medium in accordance with the GPL, and are not licensed under
|
||||||
|
the FLOSS licenses listed below, are independent and separate
|
||||||
|
works in themselves which are not derivatives of either the
|
||||||
|
Viewer Software, a work based on the Program or a FLOSS Work.
|
||||||
|
|
||||||
|
If the above conditions are not met, then the Viewer Software may only
|
||||||
|
be copied, modified, distributed or used under the terms and
|
||||||
|
conditions of the GPL or another valid licensing option from Linden
|
||||||
|
Lab.
|
||||||
|
|
||||||
|
1. FLOSS License List
|
||||||
|
|
||||||
|
License name Version(s)/Copyright Date
|
||||||
|
Academic Free License 2.0
|
||||||
|
Apache Software License 1.0/1.1/2.0
|
||||||
|
Apple Public Source License 2.0
|
||||||
|
Artistic license From Perl 5.8.0
|
||||||
|
BSD license "July 22 1999"
|
||||||
|
Common Development and
|
||||||
|
Distribution License (CDDL) 1.0
|
||||||
|
Common Public License 1.0
|
||||||
|
GNU Library or "Lesser" General
|
||||||
|
Public License (LGPL) 2.0/2.1
|
||||||
|
Jabber Open Source License 1.0
|
||||||
|
MIT License (As listed in file MIT-License.txt) -
|
||||||
|
Mozilla Public License (MPL) 1.0/1.1
|
||||||
|
Open Software License 2.0
|
||||||
|
OpenSSL license (with
|
||||||
|
original SSLeay license) "2003" ("1998")
|
||||||
|
PHP License 3.0
|
||||||
|
Python license (CNRI Python License) -
|
||||||
|
Python Software Foundation License 2.1.1
|
||||||
|
Sleepycat License "1999"
|
||||||
|
W3C License "2001"
|
||||||
|
X11 License "2001"
|
||||||
|
Zlib/libpng License -
|
||||||
|
Zope Public License 2.0
|
||||||
|
|
||||||
|
Due to the many variants of some of the above licenses, we require
|
||||||
|
that any variant of the above licenses be identical in substance to
|
||||||
|
the form approved by the Open Source Initiative and follow the 2003
|
||||||
|
version of the Free Software Foundation's Free Software Definition
|
||||||
|
(http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of the
|
||||||
|
Open Source Definition by the Open Source Initiative
|
||||||
|
(http://www.opensource.org/docs/definition.php).
|
||||||
|
|
||||||
|
2. Definitions
|
||||||
|
|
||||||
|
Terms used, but not defined, herein shall have the meaning provided in
|
||||||
|
the GPL.
|
||||||
|
|
||||||
|
3. Applicability
|
||||||
|
|
||||||
|
This FLOSS Exception applies to all Viewer Software files that contain
|
||||||
|
a notice placed by Linden Lab saying that the Viewer Software may be
|
||||||
|
distributed under the terms of this FLOSS Exception. If you create or
|
||||||
|
distribute a work which is a work based on the Program for the Viewer
|
||||||
|
Software and any other work licensed under the GPL, then this FLOSS
|
||||||
|
Exception is not available for that work; thus, you must remove the
|
||||||
|
FLOSS Exception notice from that work and comply with the GPL in all
|
||||||
|
respects, including by retaining all GPL notices. You may choose to
|
||||||
|
redistribute a copy of the Viewer Software exclusively under the terms
|
||||||
|
of the GPL by removing the FLOSS Exception notice from that copy of
|
||||||
|
the Viewer Software, provided that the copy has never been modified by
|
||||||
|
you or any third party.
|
||||||
339
LICENSES/GPL-license.txt
Normal file
339
LICENSES/GPL-license.txt
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
36
LICENSES/LLQTWEBKIT_LICENSE.txt
Normal file
36
LICENSES/LLQTWEBKIT_LICENSE.txt
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
Source code
|
||||||
|
========
|
||||||
|
The license for the source code in this distribution should be clearly
|
||||||
|
marked on each source file. Unless otherwise specified, the source
|
||||||
|
code in this distribution ("Source Code") is provided by Linden Lab to
|
||||||
|
you under the terms of the GNU General Public License, version 2.0
|
||||||
|
("GPL"), unless you have obtained a separate licensing agreement
|
||||||
|
("Other License"), formally executed by you and Linden Lab. Terms of
|
||||||
|
the GPL can be found in GPL-license.txt in this distribution, or
|
||||||
|
online at http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/gplv2
|
||||||
|
|
||||||
|
There are special exceptions to the terms and conditions of the GPL as
|
||||||
|
it is applied to this Source Code. View the full text of the exception
|
||||||
|
in the file FLOSS-exception.txt in this software distribution, or
|
||||||
|
online at http://secondlifegrid.net/technology-programs/license-virtual-world/viewerlicensing/flossexception
|
||||||
|
|
||||||
|
By copying, modifying or distributing this software, you acknowledge
|
||||||
|
that you have read and understood your obligations described above,
|
||||||
|
and agree to abide by those obligations.
|
||||||
|
|
||||||
|
ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||||
|
WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||||
|
COMPLETENESS OR PERFORMANCE.
|
||||||
|
|
||||||
|
Logos and trademarks
|
||||||
|
==============
|
||||||
|
|
||||||
|
"Second Life" and "Linden Lab" are registered trademarks of Linden
|
||||||
|
Research, Inc. Other trademarks include (but are not limited to): the
|
||||||
|
names Linden and Linden Research, as well as the Linden Lab Hexagon
|
||||||
|
Design and the Second Life Hand Design logos.
|
||||||
|
|
||||||
|
Use of logos and trademarks are subject to the Linden Lab trademark
|
||||||
|
policy, available at:
|
||||||
|
|
||||||
|
http://secondlife.com/corporate/trademark/
|
||||||
27
README
27
README
@@ -9,15 +9,30 @@
|
|||||||
Sin-gu-la-ri-ty (noun) - a distinctive feature, a uniqueness; a point at which
|
Sin-gu-la-ri-ty (noun) - a distinctive feature, a uniqueness; a point at which
|
||||||
continuity breaks up; a point in history at which machine becomes smarter than
|
continuity breaks up; a point in history at which machine becomes smarter than
|
||||||
humanity and/or fuses with it indivisively; or simply a cool sounding word with
|
humanity and/or fuses with it indivisively; or simply a cool sounding word with
|
||||||
my initials in it :)
|
the initials S.G. in it :)
|
||||||
|
|
||||||
|
Singularity Viewer is a SecondLife(tm) protocol compatible client application.
|
||||||
|
It can be used to access SecondLife services as well as a number of others such
|
||||||
|
as those based upon the OpenSim platform.
|
||||||
|
|
||||||
|
Singulariy is maintained by a small group of volunteers who can be contacted
|
||||||
|
both, in-world (SingularityViewer group) as well on IRC (#SingularityViewer
|
||||||
|
@ FreeNode). Bug requests and features requests can be submitted through our
|
||||||
|
Issue Tracker (http://code.google.com/p/singularity-viewer/issues/list or from
|
||||||
|
the viewer menu: Help --> Bug Reporting --> Singularity Issue Tracker...)
|
||||||
|
|
||||||
Singularity Viewer is a Second Life protocol compatible client application. It
|
|
||||||
can be used to access Second LIfe service as well as a number of other such as
|
|
||||||
those based upon OpenSim plattform. It is directly based upon source code of
|
|
||||||
Ascent Viewer by Balseraph Software Group, which is in turn based upon source
|
|
||||||
code released by Linden Lab, with contributions from various sources.
|
|
||||||
|
|
||||||
As this Readme grows out of date, please refer to
|
As this Readme grows out of date, please refer to
|
||||||
|
|
||||||
http://www.singularityviewer.org/about
|
http://www.singularityviewer.org/about
|
||||||
|
|
||||||
|
|
||||||
|
00000000011111111112222222222333333333344444444445555555555666666666677777777778
|
||||||
|
12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
History
|
||||||
|
|
||||||
|
The Singularity viewer was started by Siana Gearz in November 2010 by forking it
|
||||||
|
from the Ascent Viewer, by Balseraph Software Group, which in turn was based upon
|
||||||
|
source code modified from the snowglobe source code released by Linden Lab.
|
||||||
|
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ Celierra Darling
|
|||||||
VWR-6975
|
VWR-6975
|
||||||
Cron Stardust
|
Cron Stardust
|
||||||
VWR-10579
|
VWR-10579
|
||||||
|
STORM-1919
|
||||||
Cypren Christenson
|
Cypren Christenson
|
||||||
SNOW-129
|
SNOW-129
|
||||||
SNOW-140
|
SNOW-140
|
||||||
|
|||||||
82
doc/responders.txt
Normal file
82
doc/responders.txt
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
All Responders are derived from ResponderBase, however you normally do never derived from that directly yourself.
|
||||||
|
Instead, Responder classes are derived from one of:
|
||||||
|
|
||||||
|
1. Responder base classes
|
||||||
|
|
||||||
|
ResponderHeadersOnly -- Derived classes are used with HTTPClient::head or HTTPClient::getHeaderOnly.
|
||||||
|
ResponderWithCompleted -- Derived classes implement completed(U32, std::string const&, LLSD const&),
|
||||||
|
or completedRaw(U32, std::string const&, LLChannelDescriptors const&, buffer_ptr_t const&)
|
||||||
|
if the response is not (always) LLSD.
|
||||||
|
ResponderWithResult -- Derived classes implement result(LLSD const&) and optionally
|
||||||
|
errorWithContent(U32, std::string const&, LLSD const&) OR error(U32, std::string const&).
|
||||||
|
|
||||||
|
2. Special base classes
|
||||||
|
|
||||||
|
ResponderIgnoreBody -- Same as ResponderWithResult but already implements result() that ignored the body.
|
||||||
|
LLAssetUploadResponder -- Derived from ResponderWithResult. Base class for responders that upload assets via capabilities.
|
||||||
|
LegacyPolledResponder -- Used for old code that needs polling (do not use).
|
||||||
|
|
||||||
|
|
||||||
|
There is one non-base class Responder with a more general purpose:
|
||||||
|
|
||||||
|
3. Special purpose responders:
|
||||||
|
|
||||||
|
ResponderIgnore -- Derived from ResponderIgnoreBody. Used for "fire and forget" requests as it ignores any response.
|
||||||
|
|
||||||
|
|
||||||
|
4. Signatures.
|
||||||
|
|
||||||
|
Every final (derived) responder class must implement 'getName(void) const' and 'getHTTPTimeoutPolicy(void)',
|
||||||
|
except the base classes (this is to alert the developer they have to implement getName as it is pure virtual).
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
extern AIHTTPTimeoutPolicy myResponder_timeout; // Add 'P(myResponder)' to indra/llmessage/aihttptimeoutpolicy.cpp.
|
||||||
|
|
||||||
|
class MyResponder : public LLHTTPClient::SomeResponderBaseClass {
|
||||||
|
...
|
||||||
|
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return myResponder_timeout; }
|
||||||
|
/*virtual*/ char const* getName(void) const { return "MyResponder"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
Note the convention that the name of a AIHTTPTimeoutPolicy (what goes between the brackets of P()) is
|
||||||
|
the class name minus any 'AI' or 'LL' prefix and starting with a lowercase character.
|
||||||
|
|
||||||
|
Then, depending on the three main base classes that was derived from, the signatures should be:
|
||||||
|
|
||||||
|
class MyResponder1 : public LLHTTPClient::ResponderHeadersOnly {
|
||||||
|
/*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers);
|
||||||
|
// See for example PostImageResponder
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
class MyResponder2 : public LLHTTPClient::ResponderWithCompleted {
|
||||||
|
/*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer);
|
||||||
|
// See for example PostImageRedirectResponder
|
||||||
|
>>>OR<<<
|
||||||
|
|
||||||
|
/*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content); // See for example LLImportPostResponder
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class MyResponder3 : public LLHTTPClient::ResponderWithResult {
|
||||||
|
/*virtual*/ void result(const LLSD& content); // See for example LLInventoryModelFetchItemResponder
|
||||||
|
/*virtual*/ void error(U32 status, const std::string& reason);
|
||||||
|
>>>OR instead error()<<<
|
||||||
|
/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
|
||||||
|
// See for example LLSDMessage::EventResponder
|
||||||
|
};
|
||||||
|
|
||||||
|
Finally, if a responder derived from ResponderWithCompleted or ResponderWithResult needs to process
|
||||||
|
individual headers, you need to override 'needsHeaders':
|
||||||
|
|
||||||
|
/*virtual*/ bool needsHeaders(void) const { return true; } // See for example LLWebProfileResponders::PostImageResponder
|
||||||
|
// which will cause this to be called:
|
||||||
|
/*virtual*/ void completedHeaders(U32 status, std::string const& reason, AIHTTPReceivedHeaders const& headers);
|
||||||
|
|
||||||
|
And if it needs redirection to work (you'll get an assert if you forget this and it is being redirected):
|
||||||
|
|
||||||
|
/*virtual*/ bool followRedir(void) const { return true; } // See for example LLWebProfileResponders::ConfigResponder
|
||||||
|
|
||||||
|
This is not necessary for ResponderHeadersOnly because that already defines both.
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<key>OpenCircuit</key>
|
<key>OpenCircuit</key>
|
||||||
<map>
|
<map>
|
||||||
<key>flavor</key>
|
<key>flavor</key>
|
||||||
<string>template</string>
|
<string>llsd</string>
|
||||||
<key>trusted-sender</key>
|
<key>trusted-sender</key>
|
||||||
<boolean>false</boolean>
|
<boolean>false</boolean>
|
||||||
</map>
|
</map>
|
||||||
@@ -370,7 +370,7 @@
|
|||||||
</map>
|
</map>
|
||||||
|
|
||||||
<!-- Server to client -->
|
<!-- Server to client -->
|
||||||
<key>ParcelVoiceInfo</key>
|
<key>DisplayNameUpdate</key>
|
||||||
<map>
|
<map>
|
||||||
<key>flavor</key>
|
<key>flavor</key>
|
||||||
<string>llsd</string>
|
<string>llsd</string>
|
||||||
@@ -378,6 +378,21 @@
|
|||||||
<boolean>true</boolean>
|
<boolean>true</boolean>
|
||||||
</map>
|
</map>
|
||||||
|
|
||||||
|
<key>WindLightRefresh</key>
|
||||||
|
<map>
|
||||||
|
<key>flavor</key>
|
||||||
|
<string>llsd</string>
|
||||||
|
<key>trusted-sender</key>
|
||||||
|
<boolean>true</boolean>
|
||||||
|
</map>
|
||||||
|
|
||||||
|
<key>ParcelVoiceInfo</key>
|
||||||
|
<map>
|
||||||
|
<key>flavor</key>
|
||||||
|
<string>llsd</string>
|
||||||
|
<key>trusted-sender</key>
|
||||||
|
<boolean>true</boolean>
|
||||||
|
</map>
|
||||||
|
|
||||||
<key>ParcelNavigateMedia</key>
|
<key>ParcelNavigateMedia</key>
|
||||||
<map>
|
<map>
|
||||||
@@ -419,6 +434,22 @@
|
|||||||
<boolean>true</boolean>
|
<boolean>true</boolean>
|
||||||
</map>
|
</map>
|
||||||
|
|
||||||
|
<key>SetDisplayNameReply</key>
|
||||||
|
<map>
|
||||||
|
<key>flavor</key>
|
||||||
|
<string>llsd</string>
|
||||||
|
<key>trusted-sender</key>
|
||||||
|
<boolean>true</boolean>
|
||||||
|
</map>
|
||||||
|
|
||||||
|
<key>SimConsoleResponse</key>
|
||||||
|
<map>
|
||||||
|
<key>flavor</key>
|
||||||
|
<string>llsd</string>
|
||||||
|
<key>trusted-sender</key>
|
||||||
|
<boolean>true</boolean>
|
||||||
|
</map>
|
||||||
|
|
||||||
<key>DirLandReply</key>
|
<key>DirLandReply</key>
|
||||||
<map>
|
<map>
|
||||||
<key>flavor</key>
|
<key>flavor</key>
|
||||||
@@ -516,7 +547,23 @@
|
|||||||
<boolean>true</boolean>
|
<boolean>true</boolean>
|
||||||
</map>
|
</map>
|
||||||
|
|
||||||
<!-- UDPDeprecated Messages -->
|
<key>NavMeshStatusUpdate</key>
|
||||||
|
<map>
|
||||||
|
<key>flavor</key>
|
||||||
|
<string>llsd</string>
|
||||||
|
<key>trusted-sender</key>
|
||||||
|
<boolean>true</boolean>
|
||||||
|
</map>
|
||||||
|
|
||||||
|
<key>AgentStateUpdate</key>
|
||||||
|
<map>
|
||||||
|
<key>flavor</key>
|
||||||
|
<string>llsd</string>
|
||||||
|
<key>trusted-sender</key>
|
||||||
|
<boolean>true</boolean>
|
||||||
|
</map>
|
||||||
|
|
||||||
|
<!-- UDPDeprecated Messages -->
|
||||||
<key>ScriptRunningReply</key>
|
<key>ScriptRunningReply</key>
|
||||||
<map>
|
<map>
|
||||||
<key>flavor</key>
|
<key>flavor</key>
|
||||||
@@ -569,26 +616,9 @@
|
|||||||
<map>
|
<map>
|
||||||
<key>flavor</key>
|
<key>flavor</key>
|
||||||
<string>llsd</string>
|
<string>llsd</string>
|
||||||
<key>trusted-sender</key>
|
<key>trusted-sender</key>
|
||||||
<boolean>true</boolean>
|
<boolean>true</boolean>
|
||||||
</map>
|
</map>
|
||||||
|
|
||||||
<!-- Server to client -->
|
|
||||||
<key>DisplayNameUpdate</key>
|
|
||||||
<map>
|
|
||||||
<key>flavor</key>
|
|
||||||
<string>llsd</string>
|
|
||||||
<key>trusted-sender</key>
|
|
||||||
<boolean>true</boolean>
|
|
||||||
</map>
|
|
||||||
|
|
||||||
<key>SetDisplayNameReply</key>
|
|
||||||
<map>
|
|
||||||
<key>flavor</key>
|
|
||||||
<string>llsd</string>
|
|
||||||
<key>trusted-sender</key>
|
|
||||||
<boolean>true</boolean>
|
|
||||||
</map>
|
|
||||||
|
|
||||||
</map>
|
</map>
|
||||||
<key>capBans</key>
|
<key>capBans</key>
|
||||||
@@ -633,7 +663,7 @@
|
|||||||
<boolean>false</boolean>
|
<boolean>false</boolean>
|
||||||
|
|
||||||
<key>RequestTextureDownload</key>
|
<key>RequestTextureDownload</key>
|
||||||
<boolean>false</boolean>
|
<boolean>true</boolean>
|
||||||
|
|
||||||
<key>EventQueueGet</key>
|
<key>EventQueueGet</key>
|
||||||
<boolean>false</boolean>
|
<boolean>false</boolean>
|
||||||
@@ -685,6 +715,9 @@
|
|||||||
|
|
||||||
<key>FetchLib2</key>
|
<key>FetchLib2</key>
|
||||||
<boolean>true</boolean>
|
<boolean>true</boolean>
|
||||||
|
|
||||||
|
<key>UploadBakedTexture</key>
|
||||||
|
<boolean>true</boolean>
|
||||||
</map>
|
</map>
|
||||||
|
|
||||||
<key>messageBans</key>
|
<key>messageBans</key>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
|
|||||||
cmake_policy(SET CMP0003 OLD)
|
cmake_policy(SET CMP0003 OLD)
|
||||||
|
|
||||||
set(ROOT_PROJECT_NAME "Singularity" CACHE STRING
|
set(ROOT_PROJECT_NAME "Singularity" CACHE STRING
|
||||||
"The root project/makefile/solution name. Defaults to SecondLife.")
|
"The root project/makefile/solution name. Defaults to Singularity.")
|
||||||
project(${ROOT_PROJECT_NAME})
|
project(${ROOT_PROJECT_NAME})
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
@@ -30,7 +30,7 @@ include(BuildVersion)
|
|||||||
|
|
||||||
include(UnixInstall)
|
include(UnixInstall)
|
||||||
|
|
||||||
set (DISABLE_FATAL_WARNINGS TRUE)
|
set (DISABLE_FATAL_WARNINGS CACHE BOOL TRUE)
|
||||||
|
|
||||||
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE Release CACHE STRING
|
set(CMAKE_BUILD_TYPE Release CACHE STRING
|
||||||
@@ -46,12 +46,16 @@ endif(NOT STANDALONE)
|
|||||||
add_custom_target(prepare DEPENDS ${prepare_depends})
|
add_custom_target(prepare DEPENDS ${prepare_depends})
|
||||||
|
|
||||||
add_subdirectory(cmake)
|
add_subdirectory(cmake)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}cwdebug)
|
add_subdirectory(${LIBS_OPEN_PREFIX}aistatemachine)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
|
||||||
|
add_subdirectory(${LIBS_OPEN_PREFIX}llappearance)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}libopenjpeg)
|
add_subdirectory(${LIBS_OPEN_PREFIX}libopenjpeg)
|
||||||
|
add_subdirectory(${LIBS_OPEN_PREFIX}libhacd)
|
||||||
|
add_subdirectory(${LIBS_OPEN_PREFIX}libndhacd)
|
||||||
|
add_subdirectory(${LIBS_OPEN_PREFIX}libpathing)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llmath)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llmath)
|
||||||
@@ -62,85 +66,54 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llvfs)
|
|||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llwindow)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llwindow)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)
|
||||||
|
|
||||||
if (EXISTS ${LIBS_CLOSED_DIR}llkdu AND NOT STANDALONE)
|
if(STANDALONE)
|
||||||
add_subdirectory(${LIBS_CLOSED_PREFIX}llkdu)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llqtwebkit)
|
||||||
endif (EXISTS ${LIBS_CLOSED_DIR}llkdu AND NOT STANDALONE)
|
endif(STANDALONE)
|
||||||
|
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}lscript)
|
#add_subdirectory(${LIBS_OPEN_PREFIX}lscript)
|
||||||
|
|
||||||
if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
||||||
add_subdirectory(${LIBS_CLOSED_PREFIX}copy_win_scripts)
|
add_subdirectory(${LIBS_CLOSED_PREFIX}copy_win_scripts)
|
||||||
endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
|
||||||
|
|
||||||
add_custom_target(viewer)
|
add_custom_target(viewer)
|
||||||
if (VIEWER)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
|
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
|
|
||||||
|
|
||||||
# viewer plugins directory
|
# viewer plugins directory
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}plugins)
|
add_subdirectory(${LIBS_OPEN_PREFIX}plugins)
|
||||||
|
|
||||||
# llplugin testbed code (is this the right way to include it?)
|
# llplugin testbed code (is this the right way to include it?)
|
||||||
#if (NOT LINUX)
|
#if (NOT LINUX)
|
||||||
# add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
|
# add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
|
||||||
#endif (NOT LINUX)
|
#endif (NOT LINUX)
|
||||||
|
|
||||||
if (LINUX)
|
|
||||||
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
|
|
||||||
add_dependencies(viewer linux-crash-logger-strip-target)
|
|
||||||
elseif (DARWIN)
|
|
||||||
#add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
|
|
||||||
#add_subdirectory(${VIEWER_PREFIX}mac_updater)
|
|
||||||
add_dependencies(viewer mac-crash-logger)
|
|
||||||
#add_dependencies(viewer mac-updater)
|
|
||||||
elseif (WINDOWS)
|
|
||||||
add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
|
|
||||||
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
|
|
||||||
if (EXISTS ${VIEWER_DIR}win_setup)
|
|
||||||
add_subdirectory(${VIEWER_DIR}win_setup)
|
|
||||||
endif (EXISTS ${VIEWER_DIR}win_setup)
|
|
||||||
add_subdirectory(${VIEWER_PREFIX}win_updater)
|
|
||||||
add_dependencies(viewer windows-updater)
|
|
||||||
add_dependencies(viewer windows-crash-logger)
|
|
||||||
elseif (SOLARIS)
|
|
||||||
add_subdirectory(solaris_crash_logger)
|
|
||||||
add_dependencies(viewer solaris-crash-logger)
|
|
||||||
endif (LINUX)
|
|
||||||
|
|
||||||
add_subdirectory(${VIEWER_PREFIX}newview/statemachine)
|
|
||||||
add_subdirectory(${VIEWER_PREFIX}newview)
|
|
||||||
add_dependencies(viewer secondlife-bin)
|
|
||||||
endif (VIEWER)
|
|
||||||
|
|
||||||
# Linux builds the viewer and server in 2 separate projects
|
|
||||||
# In order for ./develop.py build server to work on linux,
|
|
||||||
# the viewer project needs a server target.
|
|
||||||
# This is not true for mac and windows.
|
|
||||||
if (LINUX)
|
if (LINUX)
|
||||||
add_custom_target(server)
|
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
|
||||||
|
add_dependencies(viewer linux-crash-logger-strip-target)
|
||||||
|
elseif (DARWIN)
|
||||||
|
#add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
|
||||||
|
#add_subdirectory(${VIEWER_PREFIX}mac_updater)
|
||||||
|
add_dependencies(viewer mac-crash-logger)
|
||||||
|
#add_dependencies(viewer mac-updater)
|
||||||
|
elseif (WINDOWS)
|
||||||
|
add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
|
||||||
|
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
|
||||||
|
if (EXISTS ${VIEWER_DIR}win_setup)
|
||||||
|
add_subdirectory(${VIEWER_DIR}win_setup)
|
||||||
|
endif (EXISTS ${VIEWER_DIR}win_setup)
|
||||||
|
add_subdirectory(${VIEWER_PREFIX}win_updater)
|
||||||
|
add_dependencies(viewer windows-updater)
|
||||||
|
add_dependencies(viewer windows-crash-logger)
|
||||||
|
elseif (SOLARIS)
|
||||||
|
add_subdirectory(solaris_crash_logger)
|
||||||
|
add_dependencies(viewer solaris-crash-logger)
|
||||||
endif (LINUX)
|
endif (LINUX)
|
||||||
if (SERVER)
|
|
||||||
if (NOT LINUX)
|
|
||||||
add_custom_target(server)
|
|
||||||
endif (NOT LINUX)
|
|
||||||
include(${SERVER_PREFIX}Server.cmake)
|
|
||||||
endif (SERVER)
|
|
||||||
|
|
||||||
# Windows builds include tools like VFS tool
|
add_subdirectory(${VIEWER_PREFIX}newview/statemachine)
|
||||||
if (SERVER)
|
add_subdirectory(${VIEWER_PREFIX}newview)
|
||||||
if (WINDOWS)
|
add_dependencies(viewer secondlife-bin)
|
||||||
add_subdirectory(${SERVER_PREFIX}tools)
|
|
||||||
endif (WINDOWS)
|
|
||||||
endif (SERVER)
|
|
||||||
|
|
||||||
# Configure prebuilt binary download. This must be done last so that
|
|
||||||
# all subdirectories have a chance to list the packages they need.
|
|
||||||
# We need scp for proprietary downloads.
|
|
||||||
if(INSTALL_PROPRIETARY)
|
|
||||||
include(FindSCP)
|
|
||||||
endif(INSTALL_PROPRIETARY)
|
|
||||||
|
|
||||||
# The use_prebuilt_binary macro in cmake/Prebuilt.cmake records
|
# The use_prebuilt_binary macro in cmake/Prebuilt.cmake records
|
||||||
# packages in the PREBUILT property of the 'prepare' target.
|
# packages in the PREBUILT property of the 'prepare' target.
|
||||||
|
|||||||
41
indra/aistatemachine/CMakeLists.txt
Normal file
41
indra/aistatemachine/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
project(aistatemachine)
|
||||||
|
|
||||||
|
include(00-Common)
|
||||||
|
include(LLCommon)
|
||||||
|
include(LLMessage)
|
||||||
|
include(LLMath)
|
||||||
|
include(LLXML)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
|
${LLMESSAGE_INCLUDE_DIRS}
|
||||||
|
${LLMATH_INCLUDE_DIRS}
|
||||||
|
${LLXML_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(aistatemachine_SOURCE_FILES
|
||||||
|
aistatemachine.cpp
|
||||||
|
aistatemachinethread.cpp
|
||||||
|
aitimer.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(aistatemachine_HEADER_FILES
|
||||||
|
CMakeLists.txt
|
||||||
|
|
||||||
|
aistatemachine.h
|
||||||
|
aistatemachinethread.h
|
||||||
|
aitimer.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(${aistatemachine_HEADER_FILES}
|
||||||
|
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
|
||||||
|
list(APPEND aistatemachine_SOURCE_FILES ${aistatemachine_HEADER_FILES})
|
||||||
|
|
||||||
|
add_library (aistatemachine ${aistatemachine_SOURCE_FILES})
|
||||||
|
add_dependencies(aistatemachine prepare)
|
||||||
|
|
||||||
1290
indra/aistatemachine/aistatemachine.cpp
Normal file
1290
indra/aistatemachine/aistatemachine.cpp
Normal file
File diff suppressed because it is too large
Load Diff
316
indra/aistatemachine/aistatemachine.h
Normal file
316
indra/aistatemachine/aistatemachine.h
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
/**
|
||||||
|
* @file aistatemachine.h
|
||||||
|
* @brief State machine base class
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 - 2013, Aleric Inglewood.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* There are special exceptions to the terms and conditions of the GPL as
|
||||||
|
* it is applied to this Source Code. View the full text of the exception
|
||||||
|
* in the file doc/FLOSS-exception.txt in this software distribution.
|
||||||
|
*
|
||||||
|
* CHANGELOG
|
||||||
|
* and additional copyright holders.
|
||||||
|
*
|
||||||
|
* 01/03/2010
|
||||||
|
* Initial version, written by Aleric Inglewood @ SL
|
||||||
|
*
|
||||||
|
* 28/02/2013
|
||||||
|
* Rewritten from scratch to fully support threading.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AISTATEMACHINE_H
|
||||||
|
#define AISTATEMACHINE_H
|
||||||
|
|
||||||
|
#include "aithreadsafe.h"
|
||||||
|
#include <llpointer.h>
|
||||||
|
#include <list>
|
||||||
|
#include <boost/signals2.hpp>
|
||||||
|
|
||||||
|
class AIStateMachine;
|
||||||
|
|
||||||
|
class AIEngine
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct QueueElementComp;
|
||||||
|
class QueueElement {
|
||||||
|
private:
|
||||||
|
LLPointer<AIStateMachine> mStateMachine;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QueueElement(AIStateMachine* statemachine) : mStateMachine(statemachine) { }
|
||||||
|
friend bool operator==(QueueElement const& e1, QueueElement const& e2) { return e1.mStateMachine == e2.mStateMachine; }
|
||||||
|
friend bool operator!=(QueueElement const& e1, QueueElement const& e2) { return e1.mStateMachine != e2.mStateMachine; }
|
||||||
|
friend struct QueueElementComp;
|
||||||
|
|
||||||
|
AIStateMachine const& statemachine(void) const { return *mStateMachine; }
|
||||||
|
AIStateMachine& statemachine(void) { return *mStateMachine; }
|
||||||
|
};
|
||||||
|
struct QueueElementComp {
|
||||||
|
inline bool operator()(QueueElement const& e1, QueueElement const& e2) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::list<QueueElement> queued_type;
|
||||||
|
struct engine_state_type {
|
||||||
|
queued_type list;
|
||||||
|
bool waiting;
|
||||||
|
engine_state_type(void) : waiting(false) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
AIThreadSafeSimpleDC<engine_state_type, LLCondition> mEngineState;
|
||||||
|
typedef AIAccessConst<engine_state_type, LLCondition> engine_state_type_crat;
|
||||||
|
typedef AIAccess<engine_state_type, LLCondition> engine_state_type_rat;
|
||||||
|
typedef AIAccess<engine_state_type, LLCondition> engine_state_type_wat;
|
||||||
|
char const* mName;
|
||||||
|
|
||||||
|
static U64 sMaxCount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIEngine(char const* name) : mName(name) { }
|
||||||
|
|
||||||
|
void add(AIStateMachine* state_machine);
|
||||||
|
|
||||||
|
void mainloop(void);
|
||||||
|
void threadloop(void);
|
||||||
|
void wake_up(void);
|
||||||
|
void flush(void);
|
||||||
|
|
||||||
|
char const* name(void) const { return mName; }
|
||||||
|
|
||||||
|
static void setMaxCount(F32 StateMachineMaxTime);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern AIEngine gMainThreadEngine;
|
||||||
|
extern AIEngine gStateMachineThreadEngine;
|
||||||
|
|
||||||
|
class AIStateMachine : public LLThreadSafeRefCount
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef U32 state_type; //!< The type of run_state
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// The type of event that causes multiplex() to be called.
|
||||||
|
enum event_type {
|
||||||
|
initial_run,
|
||||||
|
schedule_run,
|
||||||
|
normal_run,
|
||||||
|
insert_abort
|
||||||
|
};
|
||||||
|
// The type of mState
|
||||||
|
enum base_state_type {
|
||||||
|
bs_reset, // Idle state before run() is called. Reference count is zero (except for a possible external LLPointer).
|
||||||
|
bs_initialize, // State after run() and before/during initialize_impl().
|
||||||
|
bs_multiplex, // State after initialize_impl() before finish() or abort().
|
||||||
|
bs_abort,
|
||||||
|
bs_finish,
|
||||||
|
bs_callback,
|
||||||
|
bs_killed
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
static state_type const max_state = bs_killed + 1;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct multiplex_state_type {
|
||||||
|
base_state_type base_state;
|
||||||
|
AIEngine* current_engine; // Current engine.
|
||||||
|
multiplex_state_type(void) : base_state(bs_reset), current_engine(NULL) { }
|
||||||
|
};
|
||||||
|
struct sub_state_type {
|
||||||
|
state_type run_state;
|
||||||
|
state_type advance_state;
|
||||||
|
bool reset;
|
||||||
|
bool need_run;
|
||||||
|
bool idle;
|
||||||
|
bool skip_idle;
|
||||||
|
bool aborted;
|
||||||
|
bool finished;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Base state.
|
||||||
|
AIThreadSafeSimpleDC<multiplex_state_type> mState;
|
||||||
|
typedef AIAccessConst<multiplex_state_type> multiplex_state_type_crat;
|
||||||
|
typedef AIAccess<multiplex_state_type> multiplex_state_type_rat;
|
||||||
|
typedef AIAccess<multiplex_state_type> multiplex_state_type_wat;
|
||||||
|
// Sub state.
|
||||||
|
AIThreadSafeSimpleDC<sub_state_type> mSubState;
|
||||||
|
typedef AIAccessConst<sub_state_type> sub_state_type_crat;
|
||||||
|
typedef AIAccess<sub_state_type> sub_state_type_rat;
|
||||||
|
typedef AIAccess<sub_state_type> sub_state_type_wat;
|
||||||
|
|
||||||
|
// Mutex protecting everything below and making sure only one thread runs the state machine at a time.
|
||||||
|
LLMutex mMultiplexMutex;
|
||||||
|
// Mutex that is locked while calling *_impl() functions and the call back.
|
||||||
|
LLMutex mRunMutex;
|
||||||
|
|
||||||
|
S64 mSleep; //!< Non-zero while the state machine is sleeping.
|
||||||
|
|
||||||
|
// Callback facilities.
|
||||||
|
// From within an other state machine:
|
||||||
|
LLPointer<AIStateMachine> mParent; // The parent object that started this state machine, or NULL if there isn't any.
|
||||||
|
state_type mNewParentState; // The state at which the parent should continue upon a successful finish.
|
||||||
|
bool mAbortParent; // If true, abort parent on abort(). Otherwise continue as normal.
|
||||||
|
bool mOnAbortSignalParent; // If true and mAbortParent is false, change state of parent even on abort.
|
||||||
|
// From outside a state machine:
|
||||||
|
struct callback_type {
|
||||||
|
typedef boost::signals2::signal<void (bool)> signal_type;
|
||||||
|
callback_type(signal_type::slot_type const& slot) { connection = signal.connect(slot); }
|
||||||
|
~callback_type() { connection.disconnect(); }
|
||||||
|
void callback(bool success) const { signal(success); }
|
||||||
|
private:
|
||||||
|
boost::signals2::connection connection;
|
||||||
|
signal_type signal;
|
||||||
|
};
|
||||||
|
callback_type* mCallback; // Pointer to signal/connection, or NULL when not connected.
|
||||||
|
|
||||||
|
// Engine stuff.
|
||||||
|
AIEngine* mDefaultEngine; // Default engine.
|
||||||
|
AIEngine* mYieldEngine; // Requested engine.
|
||||||
|
|
||||||
|
#ifdef SHOW_ASSERT
|
||||||
|
// Debug stuff.
|
||||||
|
AIThreadID mThreadId; // The thread currently running multiplex().
|
||||||
|
base_state_type mDebugLastState; // The previous state that multiplex() had a normal run with.
|
||||||
|
bool mDebugShouldRun; // Set if we found evidence that we should indeed call multiplex_impl().
|
||||||
|
bool mDebugAborted; // True when abort() was called.
|
||||||
|
bool mDebugContPending; // True while cont() was called by not handled yet.
|
||||||
|
bool mDebugSetStatePending; // True while set_state() was called by not handled yet.
|
||||||
|
bool mDebugAdvanceStatePending; // True while advance_state() was called by not handled yet.
|
||||||
|
bool mDebugRefCalled; // True when ref() is called (or will be called within the critial area of mMultiplexMutex).
|
||||||
|
#endif
|
||||||
|
U64 mRuntime; // Total time spent running in the main thread (in clocks).
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIStateMachine(void) : mCallback(NULL), mDefaultEngine(NULL), mYieldEngine(NULL),
|
||||||
|
#ifdef SHOW_ASSERT
|
||||||
|
mThreadId(AIThreadID::none), mDebugLastState(bs_killed), mDebugShouldRun(false), mDebugAborted(false), mDebugContPending(false),
|
||||||
|
mDebugSetStatePending(false), mDebugAdvanceStatePending(false), mDebugRefCalled(false),
|
||||||
|
#endif
|
||||||
|
mRuntime(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// The user should call finish() (or abort(), or kill() from the call back when finish_impl() calls run()), not delete a class derived from AIStateMachine directly.
|
||||||
|
virtual ~AIStateMachine() { llassert(multiplex_state_type_rat(mState)->base_state == bs_killed); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
// These functions may be called directly after creation, or from within finish_impl(), or from the call back function.
|
||||||
|
void run(LLPointer<AIStateMachine> parent, state_type new_parent_state, bool abort_parent = true, bool on_abort_signal_parent = true, AIEngine* default_engine = &gMainThreadEngine);
|
||||||
|
void run(callback_type::signal_type::slot_type const& slot, AIEngine* default_engine = &gMainThreadEngine);
|
||||||
|
void run(void) { run(NULL, 0, false, true, mDefaultEngine); }
|
||||||
|
|
||||||
|
// This function may only be called from the call back function (and cancels a call to run() from finish_impl()).
|
||||||
|
void kill(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// This function can be called from initialize_impl() and multiplex_impl() (both called from within multiplex()).
|
||||||
|
void set_state(state_type new_state); // Run this state the NEXT loop.
|
||||||
|
// These functions can only be called from within multiplex_impl().
|
||||||
|
void idle(void); // Go idle unless cont() or advance_state() were called since the start of the current loop, or until they are called.
|
||||||
|
void finish(void); // Mark that the state machine finished and schedule the call back.
|
||||||
|
void yield(void); // Yield to give CPU to other state machines, but do not go idle.
|
||||||
|
void yield(AIEngine* engine); // Yield to give CPU to other state machines, but do not go idle. Continue running from engine 'engine'.
|
||||||
|
void yield_frame(unsigned int frames); // Run from the main-thread engine after at least 'frames' frames have passed.
|
||||||
|
void yield_ms(unsigned int ms); // Run from the main-thread engine after roughly 'ms' miliseconds have passed.
|
||||||
|
|
||||||
|
public:
|
||||||
|
// This function can be called from multiplex_imp(), but also by a child state machine and
|
||||||
|
// therefore by any thread. The child state machine should use an LLPointer<AIStateMachine>
|
||||||
|
// to access this state machine.
|
||||||
|
void abort(void); // Abort the state machine (unsuccessful finish).
|
||||||
|
|
||||||
|
// These are the only two functions that can be called by any thread at any moment.
|
||||||
|
// Those threads should use an LLPointer<AIStateMachine> to access this state machine.
|
||||||
|
void cont(void); // Guarantee at least one full run of multiplex() after this function is called. Cancels the last call to idle().
|
||||||
|
void advance_state(state_type new_state); // Guarantee at least one full run of multiplex() after this function is called
|
||||||
|
// iff new_state is larger than the last state that was processed.
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Accessors.
|
||||||
|
|
||||||
|
// Return true if the derived class is running (also when we are idle).
|
||||||
|
bool running(void) const { return multiplex_state_type_crat(mState)->base_state == bs_multiplex; }
|
||||||
|
// Return true if the derived class is running and idle.
|
||||||
|
bool waiting(void) const
|
||||||
|
{
|
||||||
|
multiplex_state_type_crat state_r(mState);
|
||||||
|
return state_r->base_state == bs_multiplex && sub_state_type_crat(mSubState)->idle;
|
||||||
|
}
|
||||||
|
// Return true if the derived class is running and idle or already being aborted.
|
||||||
|
bool waiting_or_aborting(void) const
|
||||||
|
{
|
||||||
|
multiplex_state_type_crat state_r(mState);
|
||||||
|
return state_r->base_state == bs_abort || ( state_r->base_state == bs_multiplex && sub_state_type_crat(mSubState)->idle);
|
||||||
|
}
|
||||||
|
// Return true if are added to the engine.
|
||||||
|
bool active(AIEngine const* engine) const { return multiplex_state_type_crat(mState)->current_engine == engine; }
|
||||||
|
bool aborted(void) const { return sub_state_type_crat(mSubState)->aborted; }
|
||||||
|
|
||||||
|
// Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool.
|
||||||
|
typedef state_type AIStateMachine::* const bool_type;
|
||||||
|
// Return true if state machine successfully finished.
|
||||||
|
operator bool_type() const
|
||||||
|
{
|
||||||
|
sub_state_type_crat sub_state_r(mSubState);
|
||||||
|
return (sub_state_r->finished && !sub_state_r->aborted) ? &AIStateMachine::mNewParentState : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return stringified state, for debugging purposes.
|
||||||
|
char const* state_str(base_state_type state);
|
||||||
|
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||||
|
char const* event_str(event_type event);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void add(U64 count) { mRuntime += count; }
|
||||||
|
U64 getRuntime(void) const { return mRuntime; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void initialize_impl(void) = 0;
|
||||||
|
virtual void multiplex_impl(state_type run_state) = 0;
|
||||||
|
virtual void abort_impl(void) { }
|
||||||
|
virtual void finish_impl(void) { }
|
||||||
|
virtual char const* state_str_impl(state_type run_state) const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void reset(void); // Called from run() to (re)initialize a (re)start.
|
||||||
|
void multiplex(event_type event); // Called from AIEngine to step through the states (and from reset() to kick start the state machine).
|
||||||
|
state_type begin_loop(base_state_type base_state); // Called from multiplex() at the start of a loop.
|
||||||
|
void callback(void); // Called when the state machine finished.
|
||||||
|
bool sleep(U64 current_time) // Count frames if necessary and return true when the state machine is still sleeping.
|
||||||
|
{
|
||||||
|
if (mSleep == 0)
|
||||||
|
return false;
|
||||||
|
else if (mSleep < 0)
|
||||||
|
++mSleep;
|
||||||
|
else if ((U64)mSleep <= current_time)
|
||||||
|
mSleep = 0;
|
||||||
|
return mSleep != 0;
|
||||||
|
}
|
||||||
|
void force_killed(void); // Called from AIEngine::flush().
|
||||||
|
|
||||||
|
friend class AIEngine; // Calls multiplex() and force_killed().
|
||||||
|
};
|
||||||
|
|
||||||
|
bool AIEngine::QueueElementComp::operator()(QueueElement const& e1, QueueElement const& e2) const
|
||||||
|
{
|
||||||
|
return e1.mStateMachine->getRuntime() < e2.mStateMachine->getRuntime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This can be used in state_str_impl.
|
||||||
|
#define AI_CASE_RETURN(x) do { case x: return #x; } while(0)
|
||||||
|
|
||||||
|
#endif
|
||||||
193
indra/aistatemachine/aistatemachinethread.cpp
Normal file
193
indra/aistatemachine/aistatemachinethread.cpp
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/**
|
||||||
|
* @file aistatemachinethread.cpp
|
||||||
|
* @brief Implementation of AIStateMachineThread
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Aleric Inglewood.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* There are special exceptions to the terms and conditions of the GPL as
|
||||||
|
* it is applied to this Source Code. View the full text of the exception
|
||||||
|
* in the file doc/FLOSS-exception.txt in this software distribution.
|
||||||
|
*
|
||||||
|
* CHANGELOG
|
||||||
|
* and additional copyright holders.
|
||||||
|
*
|
||||||
|
* 23/01/2013
|
||||||
|
* Initial version, written by Aleric Inglewood @ SL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "linden_common.h"
|
||||||
|
#include "aistatemachinethread.h"
|
||||||
|
|
||||||
|
class AIStateMachineThreadBase::Thread : public LLThread {
|
||||||
|
private:
|
||||||
|
LLPointer<AIStateMachineThreadBase> mImpl;
|
||||||
|
bool mNeedCleanup;
|
||||||
|
public:
|
||||||
|
Thread(AIStateMachineThreadBase* impl) :
|
||||||
|
#ifdef LL_DEBUG
|
||||||
|
LLThread(impl->impl().getName()),
|
||||||
|
#else
|
||||||
|
LLThread("AIStateMachineThreadBase::Thread"),
|
||||||
|
#endif
|
||||||
|
mImpl(impl) { }
|
||||||
|
protected:
|
||||||
|
/*virtual*/ void run(void)
|
||||||
|
{
|
||||||
|
mNeedCleanup = mImpl->impl().thread_done(mImpl->impl().run());
|
||||||
|
}
|
||||||
|
/*virtual*/ void terminated(void)
|
||||||
|
{
|
||||||
|
mStatus = STOPPED;
|
||||||
|
if (mNeedCleanup)
|
||||||
|
{
|
||||||
|
// The state machine that started us has disappeared! Clean up ourselves.
|
||||||
|
|
||||||
|
// This is OK now because in our case nobody is watching us and having set
|
||||||
|
// the status to STOPPED didn't change anything really, although it will
|
||||||
|
// prevent LLThread::shutdown from blocking a whole minute and then calling
|
||||||
|
// apr_thread_exit to never return! Normally, the LLThread might be deleted
|
||||||
|
// immediately (by the main thread) after setting mStatus to STOPPED.
|
||||||
|
Thread::completed(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
// TODO: Implement a thread pool. For now, just create a new one every time.
|
||||||
|
static Thread* allocate(AIStateMachineThreadBase* impl) { return new Thread(impl); }
|
||||||
|
static void completed(Thread* threadp) { delete threadp; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// MAIN THREAD
|
||||||
|
|
||||||
|
char const* AIStateMachineThreadBase::state_str_impl(state_type run_state) const
|
||||||
|
{
|
||||||
|
switch(run_state)
|
||||||
|
{
|
||||||
|
AI_CASE_RETURN(start_thread);
|
||||||
|
AI_CASE_RETURN(wait_stopped);
|
||||||
|
}
|
||||||
|
return "UNKNOWN STATE";
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIStateMachineThreadBase::initialize_impl(void)
|
||||||
|
{
|
||||||
|
mThread = NULL;
|
||||||
|
mAbort = false;
|
||||||
|
set_state(start_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIStateMachineThreadBase::multiplex_impl(state_type run_state)
|
||||||
|
{
|
||||||
|
switch(run_state)
|
||||||
|
{
|
||||||
|
case start_thread:
|
||||||
|
mThread = Thread::allocate(this);
|
||||||
|
// Set next state.
|
||||||
|
set_state(wait_stopped);
|
||||||
|
idle(); // Wait till the thread returns.
|
||||||
|
mThread->start();
|
||||||
|
break;
|
||||||
|
case wait_stopped:
|
||||||
|
if (!mThread->isStopped())
|
||||||
|
break;
|
||||||
|
// We're done!
|
||||||
|
//
|
||||||
|
// We can only get here when AIThreadImpl::done called cont(), (very
|
||||||
|
// shortly after which it will be STOPPED), which means we need to do
|
||||||
|
// the clean up of the thread.
|
||||||
|
// Also, the thread has really stopped now, so it's safe to delete it.
|
||||||
|
//
|
||||||
|
// Clean up the thread.
|
||||||
|
Thread::completed(mThread);
|
||||||
|
mThread = NULL; // Stop abort_impl() from doing anything.
|
||||||
|
if (mAbort)
|
||||||
|
abort();
|
||||||
|
else
|
||||||
|
finish();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIStateMachineThreadBase::abort_impl(void)
|
||||||
|
{
|
||||||
|
if (mThread)
|
||||||
|
{
|
||||||
|
// If this AIStateMachineThreadBase still exists then the AIStateMachineThread<THREAD_IMPL>
|
||||||
|
// that is derived from it still exists and therefore its member THREAD_IMPL also still exists
|
||||||
|
// and therefore impl() is valid.
|
||||||
|
bool need_cleanup = impl().state_machine_done(mThread); // Signal the fact that we aborted.
|
||||||
|
if (need_cleanup)
|
||||||
|
{
|
||||||
|
// This is an unlikely race condition. We have been aborted by our parent,
|
||||||
|
// but at the same time the thread finished!
|
||||||
|
// We can only get here when AIThreadImpl::thread_done already returned
|
||||||
|
// (VERY shortly after the thread will stop (if not already)).
|
||||||
|
// Just go into a tight loop while waiting for that, when it is safe
|
||||||
|
// to clean up the thread.
|
||||||
|
while (!mThread->isStopped())
|
||||||
|
{
|
||||||
|
mThread->yield();
|
||||||
|
}
|
||||||
|
Thread::completed(mThread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The thread is still happily running (and will clean up itself).
|
||||||
|
// Lets make sure we're not flooded with this situation.
|
||||||
|
llwarns << "Thread state machine aborted while the thread is still running. That is a waste of CPU and should be avoided." << llendl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AIThreadImpl::state_machine_done(LLThread* threadp)
|
||||||
|
{
|
||||||
|
StateMachineThread_wat state_machine_thread_w(mStateMachineThread);
|
||||||
|
AIStateMachineThreadBase* state_machine_thread = *state_machine_thread_w;
|
||||||
|
bool need_cleanup = !state_machine_thread;
|
||||||
|
if (!need_cleanup)
|
||||||
|
{
|
||||||
|
// If state_machine_thread is non-NULL, then AIThreadImpl::thread_done wasnt called yet
|
||||||
|
// (or at least didn't return yet) which means the thread is still running.
|
||||||
|
// Try telling the thread that it can stop.
|
||||||
|
threadp->setQuitting();
|
||||||
|
// Finally, mark that we are NOT going to do the cleanup by setting mStateMachineThread to NULL.
|
||||||
|
*state_machine_thread_w = NULL;
|
||||||
|
}
|
||||||
|
return need_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AIStateMachineThread THREAD
|
||||||
|
|
||||||
|
bool AIThreadImpl::thread_done(bool result)
|
||||||
|
{
|
||||||
|
StateMachineThread_wat state_machine_thread_w(mStateMachineThread);
|
||||||
|
AIStateMachineThreadBase* state_machine_thread = *state_machine_thread_w;
|
||||||
|
bool need_cleanup = !state_machine_thread;
|
||||||
|
if (!need_cleanup)
|
||||||
|
{
|
||||||
|
// If state_machine_thread is non-NULL then AIThreadImpl::abort_impl wasn't called,
|
||||||
|
// which means the state machine still exists. In fact, it should be in the waiting() state.
|
||||||
|
// It can also happen that the state machine is being aborted right now.
|
||||||
|
llassert(state_machine_thread->waiting_or_aborting());
|
||||||
|
state_machine_thread->schedule_abort(!result);
|
||||||
|
// Note that if the state machine is not running (being aborted, ie - hanging in abort_impl
|
||||||
|
// waiting for the lock on mStateMachineThread) then this is simply ignored.
|
||||||
|
state_machine_thread->cont();
|
||||||
|
// Finally, mark that we are NOT going to do the cleanup by setting mStateMachineThread to NULL.
|
||||||
|
*state_machine_thread_w = NULL;
|
||||||
|
}
|
||||||
|
return need_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
233
indra/aistatemachine/aistatemachinethread.h
Normal file
233
indra/aistatemachine/aistatemachinethread.h
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
/**
|
||||||
|
* @file aistatemachinethread.h
|
||||||
|
* @brief Run code in a thread.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Aleric Inglewood.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* There are special exceptions to the terms and conditions of the GPL as
|
||||||
|
* it is applied to this Source Code. View the full text of the exception
|
||||||
|
* in the file doc/FLOSS-exception.txt in this software distribution.
|
||||||
|
*
|
||||||
|
* CHANGELOG
|
||||||
|
* and additional copyright holders.
|
||||||
|
*
|
||||||
|
* 23/01/2013
|
||||||
|
* Initial version, written by Aleric Inglewood @ SL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AISTATEMACHINETHREAD_H
|
||||||
|
#define AISTATEMACHINETHREAD_H
|
||||||
|
|
||||||
|
#include "aistatemachine.h"
|
||||||
|
#include "llthread.h"
|
||||||
|
#include "aithreadsafe.h"
|
||||||
|
|
||||||
|
#ifdef EXAMPLE_CODE // undefined
|
||||||
|
|
||||||
|
class HelloWorldThread : public AIThreadImpl {
|
||||||
|
private:
|
||||||
|
bool mStdErr; // input
|
||||||
|
bool mSuccess; // output
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor.
|
||||||
|
HelloWorldThread(void) : AIThreadImpl("HelloWorldThread"), // MAIN THREAD
|
||||||
|
mStdErr(false), mSuccess(false) { }
|
||||||
|
|
||||||
|
// Some initialization function (if needed).
|
||||||
|
void init(bool err) { mStdErr = err; } // MAIN THREAD
|
||||||
|
// Read back output.
|
||||||
|
bool successful(void) const { return mSuccess; }
|
||||||
|
|
||||||
|
// Mandatory signature.
|
||||||
|
/*virtual*/ bool run(void) // NEW THREAD
|
||||||
|
{
|
||||||
|
if (mStdErr)
|
||||||
|
std::cerr << "Hello world" << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "Hello world" << std::endl;
|
||||||
|
mSuccess = true;
|
||||||
|
return true; // true = finish, false = abort.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The states of this state machine.
|
||||||
|
enum hello_world_state_type {
|
||||||
|
HelloWorld_start = AIStateMachine::max_state,
|
||||||
|
HelloWorld_done
|
||||||
|
};
|
||||||
|
|
||||||
|
// The statemachine class (this is almost a template).
|
||||||
|
class HelloWorld : public AIStateMachine {
|
||||||
|
private:
|
||||||
|
LLPointer<AIStateMachineThread<HelloWorldThread> > mHelloWorld;
|
||||||
|
bool mErr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HelloWorld() : mHelloWorld(new AIStateMachineThread<HelloWorldThread>), mErr(false) { }
|
||||||
|
|
||||||
|
// Print to stderr or stdout?
|
||||||
|
void init(bool err) { mErr = err; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Call finish() (or abort()), not delete.
|
||||||
|
/*virtual*/ ~HelloWorld() { }
|
||||||
|
|
||||||
|
// Handle initializing the object.
|
||||||
|
/*virtual*/ void initialize_impl(void);
|
||||||
|
|
||||||
|
// Handle run_state.
|
||||||
|
/*virtual*/ void multiplex_impl(state_type run_state);
|
||||||
|
|
||||||
|
// Implemenation of state_str for run states.
|
||||||
|
/*virtual*/ char const* state_str_impl(state_type run_state) const
|
||||||
|
{
|
||||||
|
switch(run_state)
|
||||||
|
{
|
||||||
|
AI_CASE_RETURN(HelloWorld_start);
|
||||||
|
AI_CASE_RETURN(HelloWorld_done);
|
||||||
|
}
|
||||||
|
return "UNKNOWN STATE";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The actual implementation of this statemachine starts here!
|
||||||
|
|
||||||
|
void HelloWorld::initialize_impl(void)
|
||||||
|
{
|
||||||
|
mHelloWorld->thread_impl().init(mErr); // Initialize the thread object.
|
||||||
|
set_state(HelloWorld_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HelloWorld::multiplex_impl(state_type run_state)
|
||||||
|
{
|
||||||
|
switch (run_state)
|
||||||
|
{
|
||||||
|
case HelloWorld_start:
|
||||||
|
{
|
||||||
|
mHelloWorld->run(this, HelloWorld_done); // Run HelloWorldThread and set the state of 'this' to HelloWorld_done when finished.
|
||||||
|
idle(HelloWorld_start); // Always go idle after starting a thread!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HelloWorld_done:
|
||||||
|
{
|
||||||
|
// We're done. Lets also abort when the thread reported no success.
|
||||||
|
if (mHelloWorld->thread_impl().successful()) // Read output/result of thread object.
|
||||||
|
finish();
|
||||||
|
else
|
||||||
|
abort();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EXAMPLE CODE
|
||||||
|
|
||||||
|
class AIStateMachineThreadBase;
|
||||||
|
|
||||||
|
// Derive from this to implement the code that must run in another thread.
|
||||||
|
class AIThreadImpl {
|
||||||
|
private:
|
||||||
|
template<typename THREAD_IMPL> friend class AIStateMachineThread;
|
||||||
|
typedef AIAccess<AIStateMachineThreadBase*> StateMachineThread_wat;
|
||||||
|
AIThreadSafeSimpleDC<AIStateMachineThreadBase*> mStateMachineThread;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool run(void) = 0;
|
||||||
|
bool thread_done(bool result);
|
||||||
|
bool state_machine_done(LLThread* threadp);
|
||||||
|
|
||||||
|
#ifdef LL_DEBUG
|
||||||
|
private:
|
||||||
|
char const* mName;
|
||||||
|
protected:
|
||||||
|
AIThreadImpl(char const* name = "AIStateMachineThreadBase::Thread") : mName(name) { }
|
||||||
|
public:
|
||||||
|
char const* getName(void) const { return mName; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~AIThreadImpl() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
// The base class for statemachine threads.
|
||||||
|
class AIStateMachineThreadBase : public AIStateMachine {
|
||||||
|
private:
|
||||||
|
// The actual thread (derived from LLThread).
|
||||||
|
class Thread;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef AIStateMachine direct_base_type;
|
||||||
|
|
||||||
|
// The states of this state machine.
|
||||||
|
enum thread_state_type {
|
||||||
|
start_thread = direct_base_type::max_state, // Start the thread (if necessary create it first).
|
||||||
|
wait_stopped // Wait till the thread is stopped.
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
static state_type const max_state = wait_stopped + 1;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AIStateMachineThreadBase(void) { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Handle initializing the object.
|
||||||
|
/*virtual*/ void initialize_impl(void);
|
||||||
|
|
||||||
|
// Handle mRunState.
|
||||||
|
/*virtual*/ void multiplex_impl(state_type run_state);
|
||||||
|
|
||||||
|
// Handle aborting from current bs_run state.
|
||||||
|
/*virtual*/ void abort_impl(void);
|
||||||
|
|
||||||
|
// Implemenation of state_str for run states.
|
||||||
|
/*virtual*/ char const* state_str_impl(state_type run_state) const;
|
||||||
|
|
||||||
|
// Returns a reference to the implementation code that needs to be run in the thread.
|
||||||
|
virtual AIThreadImpl& impl(void) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Thread* mThread; // The thread that the code is run in.
|
||||||
|
bool mAbort; // (Inverse of) return value of AIThreadImpl::run(). Only valid in state wait_stopped.
|
||||||
|
|
||||||
|
public:
|
||||||
|
void schedule_abort(bool do_abort) { mAbort = do_abort; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// The state machine that runs T::run() in a thread.
|
||||||
|
// THREAD_IMPL Must be derived from AIThreadImpl.
|
||||||
|
template<typename THREAD_IMPL>
|
||||||
|
class AIStateMachineThread : public AIStateMachineThreadBase {
|
||||||
|
private:
|
||||||
|
THREAD_IMPL mThreadImpl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor.
|
||||||
|
AIStateMachineThread(void)
|
||||||
|
{
|
||||||
|
*AIThreadImpl::StateMachineThread_wat(mThreadImpl.mStateMachineThread) = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accessor.
|
||||||
|
THREAD_IMPL& thread_impl(void) { return mThreadImpl; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/*virtual*/ AIThreadImpl& impl(void) { return mThreadImpl; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -31,11 +31,6 @@
|
|||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
#include "aitimer.h"
|
#include "aitimer.h"
|
||||||
|
|
||||||
enum timer_state_type {
|
|
||||||
AITimer_start = AIStateMachine::max_state,
|
|
||||||
AITimer_expired
|
|
||||||
};
|
|
||||||
|
|
||||||
char const* AITimer::state_str_impl(state_type run_state) const
|
char const* AITimer::state_str_impl(state_type run_state) const
|
||||||
{
|
{
|
||||||
switch(run_state)
|
switch(run_state)
|
||||||
@@ -43,6 +38,7 @@ char const* AITimer::state_str_impl(state_type run_state) const
|
|||||||
AI_CASE_RETURN(AITimer_start);
|
AI_CASE_RETURN(AITimer_start);
|
||||||
AI_CASE_RETURN(AITimer_expired);
|
AI_CASE_RETURN(AITimer_expired);
|
||||||
}
|
}
|
||||||
|
llassert(false);
|
||||||
return "UNKNOWN STATE";
|
return "UNKNOWN STATE";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,12 +50,12 @@ void AITimer::initialize_impl(void)
|
|||||||
|
|
||||||
void AITimer::expired(void)
|
void AITimer::expired(void)
|
||||||
{
|
{
|
||||||
set_state(AITimer_expired);
|
advance_state(AITimer_expired);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AITimer::multiplex_impl(void)
|
void AITimer::multiplex_impl(state_type run_state)
|
||||||
{
|
{
|
||||||
switch (mRunState)
|
switch (run_state)
|
||||||
{
|
{
|
||||||
case AITimer_start:
|
case AITimer_start:
|
||||||
{
|
{
|
||||||
@@ -79,18 +75,3 @@ void AITimer::abort_impl(void)
|
|||||||
{
|
{
|
||||||
mFrameTimer.cancel();
|
mFrameTimer.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AITimer::finish_impl(void)
|
|
||||||
{
|
|
||||||
// Kill object by default.
|
|
||||||
// This can be overridden by calling run() from the callback function.
|
|
||||||
kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AIPersistentTimer::finish_impl(void)
|
|
||||||
{
|
|
||||||
// Don't kill object by default.
|
|
||||||
if (aborted())
|
|
||||||
kill();
|
|
||||||
// Callback function should always call kill() or run().
|
|
||||||
}
|
|
||||||
@@ -59,6 +59,18 @@
|
|||||||
// just reuse the old ones (call the same callback).
|
// just reuse the old ones (call the same callback).
|
||||||
//
|
//
|
||||||
class AITimer : public AIStateMachine {
|
class AITimer : public AIStateMachine {
|
||||||
|
protected:
|
||||||
|
// The base class of this state machine.
|
||||||
|
typedef AIStateMachine direct_base_type;
|
||||||
|
|
||||||
|
// The different states of the state machine.
|
||||||
|
enum timer_state_type {
|
||||||
|
AITimer_start = direct_base_type::max_state,
|
||||||
|
AITimer_expired
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
static state_type const max_state = AITimer_expired + 1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AIFrameTimer mFrameTimer; //!< The actual timer that this object wraps.
|
AIFrameTimer mFrameTimer; //!< The actual timer that this object wraps.
|
||||||
F64 mInterval; //!< Input variable: interval after which the event will be generated, in seconds.
|
F64 mInterval; //!< Input variable: interval after which the event will be generated, in seconds.
|
||||||
@@ -70,7 +82,6 @@ class AITimer : public AIStateMachine {
|
|||||||
* @brief Set the interval after which the timer should expire.
|
* @brief Set the interval after which the timer should expire.
|
||||||
*
|
*
|
||||||
* @param interval Amount of time in seconds before the timer will expire.
|
* @param interval Amount of time in seconds before the timer will expire.
|
||||||
* @param True if the timer should be deleted after it expires; false means it will keep firing at regular intervals.
|
|
||||||
*
|
*
|
||||||
* Call abort() at any time to stop the timer (and delete the AITimer object).
|
* Call abort() at any time to stop the timer (and delete the AITimer object).
|
||||||
*/
|
*/
|
||||||
@@ -91,14 +102,11 @@ class AITimer : public AIStateMachine {
|
|||||||
/*virtual*/ void initialize_impl(void);
|
/*virtual*/ void initialize_impl(void);
|
||||||
|
|
||||||
// Handle mRunState.
|
// Handle mRunState.
|
||||||
/*virtual*/ void multiplex_impl(void);
|
/*virtual*/ void multiplex_impl(state_type run_state);
|
||||||
|
|
||||||
// Handle aborting from current bs_run state.
|
// Handle aborting from current bs_run state.
|
||||||
/*virtual*/ void abort_impl(void);
|
/*virtual*/ void abort_impl(void);
|
||||||
|
|
||||||
// Handle cleaning up from initialization (or post abort) state.
|
|
||||||
/*virtual*/ void finish_impl(void);
|
|
||||||
|
|
||||||
// Implemenation of state_str for run states.
|
// Implemenation of state_str for run states.
|
||||||
/*virtual*/ char const* state_str_impl(state_type run_state) const;
|
/*virtual*/ char const* state_str_impl(state_type run_state) const;
|
||||||
|
|
||||||
@@ -107,12 +115,4 @@ class AITimer : public AIStateMachine {
|
|||||||
void expired(void);
|
void expired(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Same as above but does not delete itself automatically by default after use.
|
|
||||||
// Call kill() on it yourself (from the callback function) when you're done with it!
|
|
||||||
class AIPersistentTimer : public AITimer {
|
|
||||||
protected:
|
|
||||||
// Handle cleaning up from initialization (or post abort) state.
|
|
||||||
/*virtual*/ void finish_impl(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
#
|
#
|
||||||
# Compilation options shared by all Second Life components.
|
# Compilation options shared by all Second Life components.
|
||||||
|
|
||||||
|
if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
|
||||||
|
|
||||||
include(Variables)
|
include(Variables)
|
||||||
|
|
||||||
|
|
||||||
@@ -23,25 +26,31 @@ set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING
|
|||||||
# Platform-specific compilation flags.
|
# Platform-specific compilation flags.
|
||||||
|
|
||||||
if (WINDOWS)
|
if (WINDOWS)
|
||||||
|
# Various libs are compiler specific, generate some variables here we can just use
|
||||||
|
# when we require them instead of reimplementing the test each time.
|
||||||
|
if (MSVC10)
|
||||||
|
set(MSVC_DIR 10.0)
|
||||||
|
set(MSVC_SUFFIX 100)
|
||||||
|
endif (MSVC10)
|
||||||
|
|
||||||
# Remove default /Zm1000 flag that cmake inserts
|
# Remove default /Zm1000 flag that cmake inserts
|
||||||
string (REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
string (REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
# Don't build DLLs.
|
# Don't build DLLs.
|
||||||
set(BUILD_SHARED_LIBS OFF)
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /arch:SSE2"
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP"
|
||||||
CACHE STRING "C++ compiler debug options" FORCE)
|
CACHE STRING "C++ compiler debug options" FORCE)
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /arch:SSE2"
|
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP"
|
||||||
CACHE STRING "C++ compiler release-with-debug options" FORCE)
|
CACHE STRING "C++ compiler release-with-debug options" FORCE)
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE
|
set(CMAKE_CXX_FLAGS_RELEASE
|
||||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /arch:SSE2 /fp:fast"
|
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /fp:fast -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||||
CACHE STRING "C++ compiler release options" FORCE)
|
CACHE STRING "C++ compiler release options" FORCE)
|
||||||
set(CMAKE_C_FLAGS_RELEASE
|
set(CMAKE_C_FLAGS_RELEASE
|
||||||
"${CMAKE_C_FLAGS_RELEASE} ${LL_C_FLAGS} /O2 /Zi /MD /MP /arch:SSE2 /fp:fast"
|
"${CMAKE_C_FLAGS_RELEASE} ${LL_C_FLAGS} /O2 /Zi /MD /MP /fp:fast"
|
||||||
CACHE STRING "C compiler release options" FORCE)
|
CACHE STRING "C compiler release options" FORCE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LARGEADDRESSAWARE")
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD_LIBRARIES "")
|
set(CMAKE_CXX_STANDARD_LIBRARIES "")
|
||||||
set(CMAKE_C_STANDARD_LIBRARIES "")
|
set(CMAKE_C_STANDARD_LIBRARIES "")
|
||||||
@@ -55,54 +64,24 @@ if (WINDOWS)
|
|||||||
/W3
|
/W3
|
||||||
/c
|
/c
|
||||||
/Zc:forScope
|
/Zc:forScope
|
||||||
|
/Zc:wchar_t-
|
||||||
/nologo
|
/nologo
|
||||||
/Oy-
|
/Oy-
|
||||||
|
/arch:SSE2
|
||||||
)
|
)
|
||||||
|
|
||||||
# configure win32 API for windows XP+ compatibility
|
# configure win32 API for windows XP+ compatibility
|
||||||
set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
|
set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
|
||||||
add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
|
add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
|
||||||
|
|
||||||
if(MSVC80 OR MSVC90 OR MSVC10)
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE
|
|
||||||
"${CMAKE_CXX_FLAGS_RELEASE} -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
|
||||||
CACHE STRING "C++ compiler release options" FORCE)
|
|
||||||
set(CMAKE_C_FLAGS_RELEASE
|
|
||||||
"${CMAKE_CXX_FLAGS_RELEASE} -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
|
||||||
CACHE STRING "C compiler release options" FORCE)
|
|
||||||
add_definitions(
|
|
||||||
/Zc:wchar_t-
|
|
||||||
)
|
|
||||||
endif (MSVC80 OR MSVC90 OR MSVC10)
|
|
||||||
|
|
||||||
# Are we using the crummy Visual Studio KDU build workaround?
|
# Are we using the crummy Visual Studio KDU build workaround?
|
||||||
if (NOT DISABLE_FATAL_WARNINGS)
|
if (NOT DISABLE_FATAL_WARNINGS)
|
||||||
add_definitions(/WX)
|
add_definitions(/WX)
|
||||||
endif (NOT DISABLE_FATAL_WARNINGS)
|
endif (NOT DISABLE_FATAL_WARNINGS)
|
||||||
|
|
||||||
# Various libs are compiler specific, generate some variables here we can just use
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
|
||||||
# when we require them instead of reimplementing the test each time.
|
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
|
||||||
|
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /MANIFEST:NO")
|
||||||
if (MSVC71)
|
|
||||||
set(MSVC_DIR 7.1)
|
|
||||||
set(MSVC_SUFFIX 71)
|
|
||||||
elseif (MSVC80)
|
|
||||||
set(MSVC_DIR 8.0)
|
|
||||||
set(MSVC_SUFFIX 80)
|
|
||||||
elseif (MSVC90)
|
|
||||||
set(MSVC_DIR 9.0)
|
|
||||||
set(MSVC_SUFFIX 90)
|
|
||||||
elseif (MSVC10)
|
|
||||||
set(MSVC_DIR 10.0)
|
|
||||||
set(MSVC_SUFFIX 100)
|
|
||||||
endif (MSVC71)
|
|
||||||
|
|
||||||
if (MSVC10)
|
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
|
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
|
|
||||||
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /MANIFEST:NO")
|
|
||||||
endif(MSVC10)
|
|
||||||
|
|
||||||
|
|
||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
|
|
||||||
@@ -130,7 +109,6 @@ if (LINUX)
|
|||||||
add_definitions(-DLL_IGNORE_SIGCHLD)
|
add_definitions(-DLL_IGNORE_SIGCHLD)
|
||||||
|
|
||||||
if(${CMAKE_C_COMPILER} MATCHES "gcc*")
|
if(${CMAKE_C_COMPILER} MATCHES "gcc*")
|
||||||
|
|
||||||
find_program(GXX g++)
|
find_program(GXX g++)
|
||||||
mark_as_advanced(GXX)
|
mark_as_advanced(GXX)
|
||||||
|
|
||||||
@@ -183,9 +161,6 @@ if (LINUX)
|
|||||||
|
|
||||||
# End of hacks.
|
# End of hacks.
|
||||||
|
|
||||||
#GCC Specific
|
|
||||||
add_definitions(-DCC_GCC)
|
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
||||||
|
|
||||||
if (NOT STANDALONE)
|
if (NOT STANDALONE)
|
||||||
@@ -194,10 +169,10 @@ if (LINUX)
|
|||||||
endif (NOT STANDALONE)
|
endif (NOT STANDALONE)
|
||||||
if (${ARCH} STREQUAL "x86_64")
|
if (${ARCH} STREQUAL "x86_64")
|
||||||
add_definitions(-DLINUX64=1 -pipe)
|
add_definitions(-DLINUX64=1 -pipe)
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffast-math -funroll-loops")
|
||||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -ffast-math -funroll-loops")
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ffast-math")
|
||||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers")
|
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ffast-math")
|
||||||
else (${ARCH} STREQUAL "x86_64")
|
else (${ARCH} STREQUAL "x86_64")
|
||||||
if (NOT STANDALONE)
|
if (NOT STANDALONE)
|
||||||
set(MARCH_FLAG " -march=pentium4")
|
set(MARCH_FLAG " -march=pentium4")
|
||||||
@@ -217,7 +192,6 @@ if (LINUX)
|
|||||||
mark_as_advanced(CLANGXX)
|
mark_as_advanced(CLANGXX)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DCC_CLANG
|
|
||||||
-D_FORTIFY_SOURCE=2
|
-D_FORTIFY_SOURCE=2
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -237,12 +211,10 @@ if (LINUX)
|
|||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
|
||||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
|
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
|
||||||
elseif(${CMAKE_C_COMPILER} MATCHES "icc*" AND ${CMAKE_CXX_COMPILER} MATCHES "icpc*")
|
elseif(${CMAKE_C_COMPILER} MATCHES "icc*" AND ${CMAKE_CXX_COMPILER} MATCHES "icpc*")
|
||||||
|
|
||||||
find_program(ICC icc)
|
find_program(ICC icc)
|
||||||
mark_as_advanced(ICC)
|
mark_as_advanced(ICC)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DCC_ICC
|
|
||||||
-D_FORTIFY_SOURCE=2
|
-D_FORTIFY_SOURCE=2
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -276,14 +248,23 @@ if (DARWIN)
|
|||||||
add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
|
add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
|
||||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
|
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch")
|
if(${CMAKE_C_COMPILER} MATCHES "gcc*")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch")
|
||||||
# NOTE: it's critical that the optimization flag is put in front.
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch")
|
||||||
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
# NOTE: it's critical that the optimization flag is put in front.
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
||||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||||
|
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
|
||||||
|
elseif(${CMAKE_C_COMPILER} MATCHES "clang*")
|
||||||
|
# NOTE: it's critical that the optimization flag is put in front.
|
||||||
|
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3")
|
||||||
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3")
|
||||||
|
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3")
|
||||||
|
endif()
|
||||||
endif (DARWIN)
|
endif (DARWIN)
|
||||||
|
|
||||||
|
|
||||||
@@ -325,14 +306,12 @@ else (STANDALONE)
|
|||||||
glib-2.0
|
glib-2.0
|
||||||
gstreamer-0.10
|
gstreamer-0.10
|
||||||
gtk-2.0
|
gtk-2.0
|
||||||
llfreetype2
|
freetype2
|
||||||
pango-1.0
|
pango-1.0
|
||||||
)
|
)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE)
|
||||||
|
|
||||||
if(1 EQUAL 1)
|
if(1 EQUAL 1)
|
||||||
add_definitions(-DOPENSIM_RULES=1)
|
|
||||||
add_definitions(-DMESH_ENABLED=1)
|
|
||||||
add_definitions(-DENABLE_CLASSIC_CLOUDS=1)
|
add_definitions(-DENABLE_CLASSIC_CLOUDS=1)
|
||||||
if (NOT "$ENV{SHY_MOD}" STREQUAL "")
|
if (NOT "$ENV{SHY_MOD}" STREQUAL "")
|
||||||
add_definitions(-DSHY_MOD=1)
|
add_definitions(-DSHY_MOD=1)
|
||||||
@@ -353,3 +332,5 @@ MARK_AS_ADVANCED(
|
|||||||
CMAKE_EXE_LINKER_FLAGS_RELEASE
|
CMAKE_EXE_LINKER_FLAGS_RELEASE
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE
|
CMAKE_SHARED_LINKER_FLAGS_RELEASE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
|
|
||||||
set(AISTATEMACHINE_INCLUDE_DIRS statemachine)
|
set(AISTATEMACHINE_INCLUDE_DIRS ${LIBS_OPEN_DIR}/aistatemachine)
|
||||||
set(AISTATEMACHINE_LIBRARIES statemachine)
|
set(AISTATEMACHINE_LIBRARIES aistatemachine)
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ else (STANDALONE)
|
|||||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapriconv-1.lib
|
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapriconv-1.lib
|
||||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapriconv-1.lib
|
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapriconv-1.lib
|
||||||
)
|
)
|
||||||
# Doesn't need to link with iconv.dll
|
|
||||||
set(APRICONV_LIBRARIES "")
|
|
||||||
set(APRUTIL_LIBRARIES
|
set(APRUTIL_LIBRARIES
|
||||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.lib ${APRICONV_LIBRARIES}
|
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.lib ${APRICONV_LIBRARIES}
|
||||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.lib ${APRICONV_LIBRARIES}
|
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.lib ${APRICONV_LIBRARIES}
|
||||||
@@ -33,8 +31,8 @@ else (STANDALONE)
|
|||||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.0.dylib
|
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.0.dylib
|
||||||
)
|
)
|
||||||
set(APRUTIL_LIBRARIES
|
set(APRUTIL_LIBRARIES
|
||||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.0.dylib
|
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.dylib
|
||||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.0.dylib
|
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.dylib
|
||||||
)
|
)
|
||||||
set(APRICONV_LIBRARIES iconv)
|
set(APRICONV_LIBRARIES iconv)
|
||||||
else (WINDOWS)
|
else (WINDOWS)
|
||||||
@@ -44,7 +42,7 @@ else (STANDALONE)
|
|||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/apr-1)
|
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/apr-1)
|
||||||
|
|
||||||
if (LINUX AND VIEWER)
|
if (LINUX)
|
||||||
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES})
|
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES})
|
||||||
endif (LINUX AND VIEWER)
|
endif (LINUX)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE)
|
||||||
|
|||||||
@@ -40,3 +40,11 @@ link_directories(
|
|||||||
${VORBISFILE_LIBRARY_DIRS}
|
${VORBISFILE_LIBRARY_DIRS}
|
||||||
${OGG_LIBRARY_DIRS}
|
${OGG_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(LLAUDIO_VORBIS_LIBRARIES
|
||||||
|
${VORBISENC_LIBRARIES}
|
||||||
|
${VORBISFILE_LIBRARIES}
|
||||||
|
${VORBIS_LIBRARIES}
|
||||||
|
${OGG_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -7,47 +7,33 @@ set(Boost_FIND_REQUIRED ON)
|
|||||||
if (STANDALONE)
|
if (STANDALONE)
|
||||||
include(FindBoost)
|
include(FindBoost)
|
||||||
|
|
||||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
find_package(Boost 1.40.0 COMPONENTS date_time filesystem program_options regex system thread wave)
|
||||||
set(BOOST_REGEX_LIBRARY boost_regex-mt)
|
|
||||||
set(BOOST_SYSTEM_LIBRARY boost_system-mt)
|
|
||||||
else (STANDALONE)
|
else (STANDALONE)
|
||||||
use_prebuilt_binary(boost)
|
use_prebuilt_binary(boost)
|
||||||
set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||||
|
|
||||||
if (WINDOWS)
|
if (WINDOWS)
|
||||||
set(BOOST_VERSION 1_45)
|
set(BOOST_VERSION 1_45)
|
||||||
|
set(BOOST_OPTIM_SUFFIX mt)
|
||||||
|
set(BOOST_DEBUG_SUFFIX mt-gd)
|
||||||
|
|
||||||
# SNOW-788
|
set(Boost_PROGRAM_OPTIONS_LIBRARY
|
||||||
# 00-Common.cmake alreay sets MSVC_SUFFIX to be correct for the VS we are using eg VC71, VC80, VC90 etc
|
|
||||||
# The precompiled boost libs for VC71 use a different suffix to VS80 and VS90
|
|
||||||
# This code should ensure the cmake rules are valid for any VS being used in future as long as the approprate
|
|
||||||
# boost libs are avaiable - RC.
|
|
||||||
|
|
||||||
if (MSVC71)
|
|
||||||
set(BOOST_OPTIM_SUFFIX mt-s)
|
|
||||||
set(BOOST_DEBUG_SUFFIX mt-sgd)
|
|
||||||
else (MSVC71)
|
|
||||||
set(BOOST_OPTIM_SUFFIX mt)
|
|
||||||
set(BOOST_DEBUG_SUFFIX mt-gd)
|
|
||||||
endif (MSVC71)
|
|
||||||
|
|
||||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY
|
|
||||||
optimized libboost_program_options-vc${MSVC_SUFFIX}-${BOOST_OPTIM_SUFFIX}-${BOOST_VERSION}
|
optimized libboost_program_options-vc${MSVC_SUFFIX}-${BOOST_OPTIM_SUFFIX}-${BOOST_VERSION}
|
||||||
debug libboost_program_options-vc${MSVC_SUFFIX}-${BOOST_DEBUG_SUFFIX}-${BOOST_VERSION})
|
debug libboost_program_options-vc${MSVC_SUFFIX}-${BOOST_DEBUG_SUFFIX}-${BOOST_VERSION})
|
||||||
set(BOOST_REGEX_LIBRARY
|
set(Boost_REGEX_LIBRARY
|
||||||
optimized libboost_regex-vc${MSVC_SUFFIX}-${BOOST_OPTIM_SUFFIX}-${BOOST_VERSION}
|
optimized libboost_regex-vc${MSVC_SUFFIX}-${BOOST_OPTIM_SUFFIX}-${BOOST_VERSION}
|
||||||
debug libboost_regex-vc${MSVC_SUFFIX}-${BOOST_DEBUG_SUFFIX}-${BOOST_VERSION})
|
debug libboost_regex-vc${MSVC_SUFFIX}-${BOOST_DEBUG_SUFFIX}-${BOOST_VERSION})
|
||||||
|
|
||||||
elseif (DARWIN)
|
elseif (DARWIN)
|
||||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
|
set(Boost_FILESYSTEM_LIBRARY boost_filesystem)
|
||||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
set(Boost_PROGRAM_OPTIONS_LIBRARY boost_program_options)
|
||||||
set(BOOST_REGEX_LIBRARY boost_regex-mt)
|
set(Boost_REGEX_LIBRARY boost_regex)
|
||||||
set(BOOST_SYSTEM_LIBRARY boost_system-mt)
|
set(Boost_SYSTEM_LIBRARY boost_system)
|
||||||
elseif (LINUX)
|
elseif (LINUX)
|
||||||
set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
|
set(Boost_FILESYSTEM_LIBRARY boost_filesystem-mt)
|
||||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
set(Boost_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
||||||
set(BOOST_REGEX_LIBRARY boost_regex-mt)
|
set(Boost_REGEX_LIBRARY boost_regex-mt)
|
||||||
set(BOOST_SYSTEM_LIBRARY boost_system-mt)
|
set(Boost_SYSTEM_LIBRARY boost_system-mt)
|
||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE)
|
||||||
|
|||||||
@@ -8,74 +8,97 @@ set(cmake_SOURCE_FILES
|
|||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
|
||||||
00-Common.cmake
|
00-Common.cmake
|
||||||
|
AIStateMachine.cmake
|
||||||
APR.cmake
|
APR.cmake
|
||||||
Audio.cmake
|
Audio.cmake
|
||||||
|
BasicPluginBase.cmake
|
||||||
BerkeleyDB.cmake
|
BerkeleyDB.cmake
|
||||||
Boost.cmake
|
Boost.cmake
|
||||||
BuildVersion.cmake
|
BuildVersion.cmake
|
||||||
CARes.cmake
|
CARes.cmake
|
||||||
CURL.cmake
|
|
||||||
CMakeCopyIfDifferent.cmake
|
CMakeCopyIfDifferent.cmake
|
||||||
|
CURL.cmake
|
||||||
|
Colladadom.cmake
|
||||||
|
ConfigurePkgConfig.cmake
|
||||||
|
CopyBackToSource.cmake
|
||||||
CopyWinLibs.cmake
|
CopyWinLibs.cmake
|
||||||
CSharpMacros.cmake
|
Cwdebug.cmake
|
||||||
DBusGlib.cmake
|
DBusGlib.cmake
|
||||||
DirectX.cmake
|
DirectX.cmake
|
||||||
DownloadPrebuilt.cmake.in
|
DownloadPrebuilt.cmake.in
|
||||||
ELFIO.cmake
|
ELFIO.cmake
|
||||||
EXPAT.cmake
|
EXPAT.cmake
|
||||||
|
ExamplePlugin.cmake
|
||||||
|
FMOD.cmake
|
||||||
|
FMODEX.cmake
|
||||||
FindAPR.cmake
|
FindAPR.cmake
|
||||||
FindBerkeleyDB.cmake
|
FindBerkeleyDB.cmake
|
||||||
FindCARes.cmake
|
FindCARes.cmake
|
||||||
|
FindColladadom.cmake
|
||||||
FindELFIO.cmake
|
FindELFIO.cmake
|
||||||
|
FindGLOD.cmake
|
||||||
FindGooglePerfTools.cmake
|
FindGooglePerfTools.cmake
|
||||||
FindHunSpell.cmake
|
FindHunSpell.cmake
|
||||||
FindMT.cmake
|
FindJsonCpp.cmake
|
||||||
|
FindLLQtWebkit.cmake
|
||||||
FindNDOF.cmake
|
FindNDOF.cmake
|
||||||
FindOpenJPEG.cmake
|
FindOpenJPEG.cmake
|
||||||
|
FindTut.cmake
|
||||||
FindXmlRpcEpi.cmake
|
FindXmlRpcEpi.cmake
|
||||||
FMOD.cmake
|
|
||||||
FMODEX.cmake
|
|
||||||
FreeType.cmake
|
FreeType.cmake
|
||||||
|
GLOD.cmake
|
||||||
GStreamer010Plugin.cmake
|
GStreamer010Plugin.cmake
|
||||||
|
Glui.cmake
|
||||||
|
Glut.cmake
|
||||||
GooglePerfTools.cmake
|
GooglePerfTools.cmake
|
||||||
Hunspell.cmake
|
Hunspell.cmake
|
||||||
JPEG.cmake
|
JPEG.cmake
|
||||||
|
JsonCpp.cmake
|
||||||
LLAddBuildTest.cmake
|
LLAddBuildTest.cmake
|
||||||
|
LLAppearance.cmake
|
||||||
LLAudio.cmake
|
LLAudio.cmake
|
||||||
LLCharacter.cmake
|
LLCharacter.cmake
|
||||||
LLCommon.cmake
|
LLCommon.cmake
|
||||||
LLCrashLogger.cmake
|
LLCrashLogger.cmake
|
||||||
LLDatabase.cmake
|
|
||||||
LLImage.cmake
|
LLImage.cmake
|
||||||
LLImageJ2COJ.cmake
|
LLImageJ2COJ.cmake
|
||||||
LLInventory.cmake
|
LLInventory.cmake
|
||||||
LLKDU.cmake
|
|
||||||
LLMath.cmake
|
LLMath.cmake
|
||||||
LLMessage.cmake
|
LLMessage.cmake
|
||||||
|
LLPhysicsExtensions.cmake
|
||||||
LLPlugin.cmake
|
LLPlugin.cmake
|
||||||
LLPrimitive.cmake
|
LLPrimitive.cmake
|
||||||
|
LLPhysicsExtensions.cmake
|
||||||
|
LLQtWebkit.cmake
|
||||||
LLRender.cmake
|
LLRender.cmake
|
||||||
LLScene.cmake
|
|
||||||
LLUI.cmake
|
LLUI.cmake
|
||||||
LLVFS.cmake
|
LLVFS.cmake
|
||||||
LLWindow.cmake
|
LLWindow.cmake
|
||||||
LLXML.cmake
|
LLXML.cmake
|
||||||
LScript.cmake
|
LScript.cmake
|
||||||
Linking.cmake
|
Linking.cmake
|
||||||
|
MediaPluginBase.cmake
|
||||||
NDOF.cmake
|
NDOF.cmake
|
||||||
OPENAL.cmake
|
OPENAL.cmake
|
||||||
OpenGL.cmake
|
OpenGL.cmake
|
||||||
OpenJPEG.cmake
|
OpenJPEG.cmake
|
||||||
OpenSSL.cmake
|
OpenSSL.cmake
|
||||||
PNG.cmake
|
PNG.cmake
|
||||||
Python.cmake
|
PluginAPI.cmake
|
||||||
Prebuilt.cmake
|
Prebuilt.cmake
|
||||||
|
PulseAudio.cmake
|
||||||
|
Python.cmake
|
||||||
|
Qt4.cmake
|
||||||
|
QuickTimePlugin.cmake
|
||||||
RunBuildTest.cmake
|
RunBuildTest.cmake
|
||||||
|
StateMachine.cmake
|
||||||
TemplateCheck.cmake
|
TemplateCheck.cmake
|
||||||
Tut.cmake
|
Tut.cmake
|
||||||
UI.cmake
|
UI.cmake
|
||||||
UnixInstall.cmake
|
UnixInstall.cmake
|
||||||
Variables.cmake
|
Variables.cmake
|
||||||
|
ViewerMiscLibs.cmake
|
||||||
|
WebKitLibPlugin.cmake
|
||||||
XmlRpcEpi.cmake
|
XmlRpcEpi.cmake
|
||||||
ZLIB.cmake
|
ZLIB.cmake
|
||||||
)
|
)
|
||||||
@@ -87,10 +110,6 @@ set(master_SOURCE_FILES
|
|||||||
../develop.py
|
../develop.py
|
||||||
)
|
)
|
||||||
|
|
||||||
if (SERVER)
|
|
||||||
list(APPEND master_SOURCE_FILES ../Server.cmake)
|
|
||||||
endif (SERVER)
|
|
||||||
|
|
||||||
source_group("Master Rules" FILES ${master_SOURCE_FILES})
|
source_group("Master Rules" FILES ${master_SOURCE_FILES})
|
||||||
|
|
||||||
set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES}
|
set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES}
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
# - This is a support module for easy Mono/C# handling with CMake
|
|
||||||
# It defines the following macros:
|
|
||||||
#
|
|
||||||
# ADD_CS_LIBRARY (<target> <source>)
|
|
||||||
# ADD_CS_EXECUTABLE (<target> <source>)
|
|
||||||
# INSTALL_GAC (<target>)
|
|
||||||
#
|
|
||||||
# Note that the order of the arguments is important.
|
|
||||||
#
|
|
||||||
# You can optionally set the variable CS_FLAGS to tell the macros whether
|
|
||||||
# to pass additional flags to the compiler. This is particularly useful to
|
|
||||||
# set assembly references, unsafe code, etc... These flags are always reset
|
|
||||||
# after the target was added so you don't have to care about that.
|
|
||||||
#
|
|
||||||
# copyright (c) 2007 Arno Rehn arno@arnorehn.de
|
|
||||||
#
|
|
||||||
# Redistribution and use is allowed according to the terms of the GPL license.
|
|
||||||
|
|
||||||
|
|
||||||
# ----- support macros -----
|
|
||||||
MACRO(GET_CS_LIBRARY_TARGET_DIR)
|
|
||||||
IF (NOT LIBRARY_OUTPUT_PATH)
|
|
||||||
SET(CS_LIBRARY_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
ELSE (NOT LIBRARY_OUTPUT_PATH)
|
|
||||||
SET(CS_LIBRARY_TARGET_DIR ${LIBRARY_OUTPUT_PATH})
|
|
||||||
ENDIF (NOT LIBRARY_OUTPUT_PATH)
|
|
||||||
ENDMACRO(GET_CS_LIBRARY_TARGET_DIR)
|
|
||||||
|
|
||||||
MACRO(GET_CS_EXECUTABLE_TARGET_DIR)
|
|
||||||
IF (NOT EXECUTABLE_OUTPUT_PATH)
|
|
||||||
SET(CS_EXECUTABLE_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
ELSE (NOT EXECUTABLE_OUTPUT_PATH)
|
|
||||||
SET(CS_EXECUTABLE_TARGET_DIR ${EXECUTABLE_OUTPUT_PATH})
|
|
||||||
ENDIF (NOT EXECUTABLE_OUTPUT_PATH)
|
|
||||||
ENDMACRO(GET_CS_EXECUTABLE_TARGET_DIR)
|
|
||||||
|
|
||||||
MACRO(MAKE_PROPER_FILE_LIST)
|
|
||||||
FOREACH(file ${ARGN})
|
|
||||||
# first assume it's a relative path
|
|
||||||
FILE(GLOB globbed ${CMAKE_CURRENT_SOURCE_DIR}/${file})
|
|
||||||
IF(globbed)
|
|
||||||
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file} native)
|
|
||||||
ELSE(globbed)
|
|
||||||
FILE(TO_NATIVE_PATH ${file} native)
|
|
||||||
ENDIF(globbed)
|
|
||||||
SET(proper_file_list ${proper_file_list} ${native})
|
|
||||||
SET(native "")
|
|
||||||
ENDFOREACH(file)
|
|
||||||
ENDMACRO(MAKE_PROPER_FILE_LIST)
|
|
||||||
# ----- end support macros -----
|
|
||||||
|
|
||||||
MACRO(ADD_CS_LIBRARY target)
|
|
||||||
GET_CS_LIBRARY_TARGET_DIR()
|
|
||||||
|
|
||||||
SET(target_DLL "${CS_LIBRARY_TARGET_DIR}/${target}.dll")
|
|
||||||
MAKE_PROPER_FILE_LIST(${ARGN})
|
|
||||||
FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_DLL})
|
|
||||||
|
|
||||||
SET(target_KEY "${CMAKE_CURRENT_SOURCE_DIR}/${target}.key")
|
|
||||||
SET(target_CS_FLAGS "${CS_FLAGS}")
|
|
||||||
IF(${target}_CS_FLAGS)
|
|
||||||
LIST(APPEND target_CS_FLAGS ${${target}_CS_FLAGS})
|
|
||||||
ENDIF(${target}_CS_FLAGS)
|
|
||||||
IF(EXISTS ${target_KEY})
|
|
||||||
LIST(APPEND target_CS_FLAGS -keyfile:${target_KEY})
|
|
||||||
ENDIF(EXISTS ${target_KEY})
|
|
||||||
|
|
||||||
FOREACH(ref ${${target}_REFS})
|
|
||||||
SET(ref_DLL ${CMAKE_CURRENT_BINARY_DIR}/${ref}.dll)
|
|
||||||
IF(EXISTS ${ref_DLL})
|
|
||||||
LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
|
|
||||||
ELSE(EXISTS ${ref_DLL})
|
|
||||||
LIST(APPEND target_CS_FLAGS -r:${ref})
|
|
||||||
ENDIF(EXISTS ${ref_DLL})
|
|
||||||
ENDFOREACH(ref ${${target}_REFS})
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND (OUTPUT ${target_DLL}
|
|
||||||
COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_DLL} -target:library ${proper_file_list}
|
|
||||||
MAIN_DEPENDENCY ${proper_file_list}
|
|
||||||
DEPENDS ${ARGN}
|
|
||||||
COMMENT "Building ${relative_path}")
|
|
||||||
ADD_CUSTOM_TARGET (${target} ALL DEPENDS ${target_DLL})
|
|
||||||
|
|
||||||
FOREACH(ref ${${target}_REFS})
|
|
||||||
GET_TARGET_PROPERTY(is_target ${ref} TYPE)
|
|
||||||
IF(is_target)
|
|
||||||
ADD_DEPENDENCIES(${target} ${ref})
|
|
||||||
ENDIF(is_target)
|
|
||||||
ENDFOREACH(ref ${${target}_REFS})
|
|
||||||
|
|
||||||
SET(relative_path "")
|
|
||||||
SET(proper_file_list "")
|
|
||||||
ENDMACRO(ADD_CS_LIBRARY)
|
|
||||||
|
|
||||||
MACRO(ADD_CS_EXECUTABLE target)
|
|
||||||
GET_CS_EXECUTABLE_TARGET_DIR()
|
|
||||||
|
|
||||||
# Seems like cmake doesn't like the ".exe" ending for custom commands.
|
|
||||||
# If we call it ${target}.exe, 'make' will later complain about a missing rule.
|
|
||||||
# Create a fake target instead.
|
|
||||||
SET(target_EXE "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe")
|
|
||||||
SET(target_TOUCH "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe-built")
|
|
||||||
GET_DIRECTORY_PROPERTY(clean ADDITIONAL_MAKE_CLEAN_FILES)
|
|
||||||
LIST(APPEND clean ${target}.exe)
|
|
||||||
SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${clean}")
|
|
||||||
MAKE_PROPER_FILE_LIST(${ARGN})
|
|
||||||
FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_EXE})
|
|
||||||
SET(target_CS_FLAGS "${CS_FLAGS}")
|
|
||||||
|
|
||||||
FOREACH(ref ${${target}_REFS})
|
|
||||||
SET(ref_DLL ${CMAKE_CURRENT_SOURCE_DIR}/${ref}.dll)
|
|
||||||
IF(EXISTS ${ref_DLL})
|
|
||||||
LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
|
|
||||||
ELSE(EXISTS ${ref_DLL})
|
|
||||||
LIST(APPEND target_CS_FLAGS -r:${ref})
|
|
||||||
ENDIF(EXISTS ${ref_DLL})
|
|
||||||
ENDFOREACH(ref ${${target}_REFS})
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND (OUTPUT "${target_TOUCH}"
|
|
||||||
COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_EXE} ${proper_file_list}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch ${target_TOUCH}
|
|
||||||
MAIN_DEPENDENCY ${ARGN}
|
|
||||||
DEPENDS ${ARGN}
|
|
||||||
COMMENT "Building ${relative_path}")
|
|
||||||
ADD_CUSTOM_TARGET ("${target}" ALL DEPENDS "${target_TOUCH}")
|
|
||||||
|
|
||||||
FOREACH(ref ${${target}_REFS})
|
|
||||||
GET_TARGET_PROPERTY(is_target ${ref} TYPE)
|
|
||||||
IF(is_target)
|
|
||||||
ADD_DEPENDENCIES(${target} ${ref})
|
|
||||||
ENDIF(is_target)
|
|
||||||
ENDFOREACH(ref ${${target}_REFS})
|
|
||||||
|
|
||||||
SET(relative_path "")
|
|
||||||
SET(proper_file_list "")
|
|
||||||
ENDMACRO(ADD_CS_EXECUTABLE)
|
|
||||||
|
|
||||||
MACRO(INSTALL_GAC target)
|
|
||||||
GET_CS_LIBRARY_TARGET_DIR()
|
|
||||||
|
|
||||||
INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${GACUTIL_EXECUTABLE} -i ${CS_LIBRARY_TARGET_DIR}/${target}.dll -package 2.0)")
|
|
||||||
ENDMACRO(INSTALL_GAC target)
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
include(Prebuilt)
|
include(Prebuilt)
|
||||||
|
|
||||||
set(CURL_FIND_QUIETLY ON)
|
set(CURL_FIND_QUIETLY OFF)
|
||||||
set(CURL_FIND_REQUIRED ON)
|
set(CURL_FIND_REQUIRED ON)
|
||||||
|
|
||||||
if (STANDALONE)
|
if (STANDALONE)
|
||||||
@@ -14,6 +14,9 @@ else (STANDALONE)
|
|||||||
optimized libcurl)
|
optimized libcurl)
|
||||||
else (WINDOWS)
|
else (WINDOWS)
|
||||||
set(CURL_LIBRARIES curl)
|
set(CURL_LIBRARIES curl)
|
||||||
|
if(LINUX AND WORD_SIZE EQUAL 64)
|
||||||
|
list(APPEND CURL_LIBRARIES idn)
|
||||||
|
endif(LINUX AND WORD_SIZE EQUAL 64)
|
||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE)
|
||||||
|
|||||||
46
indra/cmake/Colladadom.cmake
Normal file
46
indra/cmake/Colladadom.cmake
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
include(Prebuilt)
|
||||||
|
|
||||||
|
set(COLLADADOM_FIND_QUIETLY OFF)
|
||||||
|
set(COLLADADOM_FIND_REQUIRED ON)
|
||||||
|
|
||||||
|
if (STANDALONE)
|
||||||
|
include (FindColladadom)
|
||||||
|
else (STANDALONE)
|
||||||
|
use_prebuilt_binary(colladadom)
|
||||||
|
|
||||||
|
if (NOT WINDOWS)
|
||||||
|
use_prebuilt_binary(pcre)
|
||||||
|
endif (NOT WINDOWS)
|
||||||
|
|
||||||
|
if (NOT DARWIN AND NOT WINDOWS)
|
||||||
|
use_prebuilt_binary(libxml)
|
||||||
|
endif (NOT DARWIN AND NOT WINDOWS)
|
||||||
|
|
||||||
|
set(COLLADADOM_INCLUDE_DIRS
|
||||||
|
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/collada
|
||||||
|
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/collada/1.4
|
||||||
|
)
|
||||||
|
|
||||||
|
if (WINDOWS)
|
||||||
|
add_definitions(-DDOM_DYNAMIC)
|
||||||
|
set(COLLADADOM_LIBRARIES
|
||||||
|
debug libcollada14dom22-d
|
||||||
|
optimized libcollada14dom22
|
||||||
|
debug libboost_filesystem-vc100-mt-gd-1_45.lib
|
||||||
|
optimized libboost_filesystem-vc100-mt-1_45.lib
|
||||||
|
debug libboost_system-vc100-mt-gd-1_45.lib
|
||||||
|
optimized libboost_system-vc100-mt-1_45.lib
|
||||||
|
)
|
||||||
|
else (WINDOWS)
|
||||||
|
set(COLLADADOM_LIBRARIES
|
||||||
|
collada14dom
|
||||||
|
minizip
|
||||||
|
xml2
|
||||||
|
pcrecpp
|
||||||
|
pcre
|
||||||
|
)
|
||||||
|
endif (WINDOWS)
|
||||||
|
endif (STANDALONE)
|
||||||
|
|
||||||
74
indra/cmake/ConfigurePkgConfig.cmake
Normal file
74
indra/cmake/ConfigurePkgConfig.cmake
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
SET(DEBUG_PKG_CONFIG "YES")
|
||||||
|
|
||||||
|
# Don't change this if manually set by user.
|
||||||
|
IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
|
||||||
|
|
||||||
|
# Guess at architecture-specific system library paths.
|
||||||
|
if (WORD_SIZE EQUAL 32)
|
||||||
|
SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib)
|
||||||
|
SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib)
|
||||||
|
SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu)
|
||||||
|
SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu)
|
||||||
|
else (WORD_SIZE EQUAL 32)
|
||||||
|
SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib)
|
||||||
|
SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib)
|
||||||
|
SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu)
|
||||||
|
SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu)
|
||||||
|
endif (WORD_SIZE EQUAL 32)
|
||||||
|
|
||||||
|
# Use DPKG architecture, if available.
|
||||||
|
IF (${DPKG_ARCH})
|
||||||
|
SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH})
|
||||||
|
SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH})
|
||||||
|
ENDIF (${DPKG_ARCH})
|
||||||
|
|
||||||
|
# Explicitly include anything listed in PKG_CONFIG_PATH
|
||||||
|
string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}")
|
||||||
|
FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST})
|
||||||
|
SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig")
|
||||||
|
ENDFOREACH(PKG_CONFIG_DIR)
|
||||||
|
|
||||||
|
# Look for valid pkgconfig directories.
|
||||||
|
FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH)
|
||||||
|
FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS})
|
||||||
|
FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS})
|
||||||
|
FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS})
|
||||||
|
FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS})
|
||||||
|
|
||||||
|
# Add anything we found to our list.
|
||||||
|
IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)
|
||||||
|
SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig")
|
||||||
|
ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)
|
||||||
|
|
||||||
|
IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)
|
||||||
|
SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig")
|
||||||
|
ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)
|
||||||
|
|
||||||
|
IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)
|
||||||
|
SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig")
|
||||||
|
ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)
|
||||||
|
|
||||||
|
IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)
|
||||||
|
SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig")
|
||||||
|
ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)
|
||||||
|
|
||||||
|
IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)
|
||||||
|
SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig")
|
||||||
|
ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)
|
||||||
|
|
||||||
|
# Also add some non-architecture specific package locations.
|
||||||
|
SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig")
|
||||||
|
|
||||||
|
# Remove first unwanted ':'
|
||||||
|
string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS)
|
||||||
|
|
||||||
|
# Set PKG_CONFIG_LIBDIR environment.
|
||||||
|
SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS})
|
||||||
|
ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
|
||||||
|
|
||||||
|
IF(DEBUG_PKG_CONFIG)
|
||||||
|
MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
|
||||||
|
ENDIF(DEBUG_PKG_CONFIG)
|
||||||
|
|
||||||
@@ -31,6 +31,8 @@ set(debug_files
|
|||||||
libapriconv-1.dll
|
libapriconv-1.dll
|
||||||
libeay32.dll
|
libeay32.dll
|
||||||
ssleay32.dll
|
ssleay32.dll
|
||||||
|
libcollada14dom22-d.dll
|
||||||
|
glod.dll
|
||||||
)
|
)
|
||||||
|
|
||||||
copy_if_different(
|
copy_if_different(
|
||||||
@@ -210,13 +212,16 @@ set(release_files
|
|||||||
libapriconv-1.dll
|
libapriconv-1.dll
|
||||||
libeay32.dll
|
libeay32.dll
|
||||||
ssleay32.dll
|
ssleay32.dll
|
||||||
|
libcollada14dom22.dll
|
||||||
|
glod.dll
|
||||||
)
|
)
|
||||||
|
|
||||||
if(FMODEX)
|
if(FMODEX)
|
||||||
find_path(FMODEX_BINARY_DIR fmodex.dll
|
find_path(FMODEX_BINARY_DIR fmodex.dll
|
||||||
${release_src_dir}
|
"${release_src_dir}"
|
||||||
${FMODEX_SDK_DIR}/api
|
"${FMODEX_SDK_DIR}/api"
|
||||||
${FMODEX_SDK_DIR}
|
"${FMODEX_SDK_DIR}"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
)
|
)
|
||||||
|
|
||||||
if(FMODEX_BINARY_DIR)
|
if(FMODEX_BINARY_DIR)
|
||||||
@@ -280,53 +285,6 @@ copy_if_different(
|
|||||||
)
|
)
|
||||||
set(all_targets ${all_targets} ${out_targets})
|
set(all_targets ${all_targets} ${out_targets})
|
||||||
|
|
||||||
set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu")
|
|
||||||
if(EXISTS ${internal_llkdu_path})
|
|
||||||
set(internal_llkdu_src "${CMAKE_BINARY_DIR}/llkdu/${CMAKE_CFG_INTDIR}/llkdu.dll")
|
|
||||||
set(llkdu_dst "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llkdu.dll")
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ${llkdu_dst}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${internal_llkdu_src} ${llkdu_dst}
|
|
||||||
DEPENDS ${internal_llkdu_src}
|
|
||||||
COMMENT "Copying llkdu.dll ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
|
|
||||||
)
|
|
||||||
set(all_targets ${all_targets} ${llkdu_dst})
|
|
||||||
else(EXISTS ${internal_llkdu_path})
|
|
||||||
if (EXISTS "${debug_src_dir}/llkdu.dll")
|
|
||||||
set(debug_llkdu_src "${debug_src_dir}/llkdu.dll")
|
|
||||||
set(debug_llkdu_dst "${CMAKE_CURRENT_BINARY_DIR}/Debug/llkdu.dll")
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ${debug_llkdu_dst}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${debug_llkdu_src} ${debug_llkdu_dst}
|
|
||||||
DEPENDS ${debug_llkdu_src}
|
|
||||||
COMMENT "Copying llkdu.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug"
|
|
||||||
)
|
|
||||||
set(all_targets ${all_targets} ${debug_llkdu_dst})
|
|
||||||
endif (EXISTS "${debug_src_dir}/llkdu.dll")
|
|
||||||
|
|
||||||
if (EXISTS "${release_src_dir}/llkdu.dll")
|
|
||||||
set(release_llkdu_src "${release_src_dir}/llkdu.dll")
|
|
||||||
set(release_llkdu_dst "${CMAKE_CURRENT_BINARY_DIR}/Release/llkdu.dll")
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ${release_llkdu_dst}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${release_llkdu_src} ${release_llkdu_dst}
|
|
||||||
DEPENDS ${release_llkdu_src}
|
|
||||||
COMMENT "Copying llkdu.dll ${CMAKE_CURRENT_BINARY_DIR}/Release"
|
|
||||||
)
|
|
||||||
set(all_targets ${all_targets} ${release_llkdu_dst})
|
|
||||||
|
|
||||||
set(relwithdebinfo_llkdu_dst "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llkdu.dll")
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ${relwithdebinfo_llkdu_dst}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${release_llkdu_src} ${relwithdebinfo_llkdu_dst}
|
|
||||||
DEPENDS ${release_llkdu_src}
|
|
||||||
COMMENT "Copying llkdu.dll ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo"
|
|
||||||
)
|
|
||||||
set(all_targets ${all_targets} ${relwithdebinfo_llkdu_dst})
|
|
||||||
endif (EXISTS "${release_src_dir}/llkdu.dll")
|
|
||||||
|
|
||||||
endif (EXISTS ${internal_llkdu_path})
|
|
||||||
|
|
||||||
# Copy MS C runtime dlls, required for packaging.
|
# Copy MS C runtime dlls, required for packaging.
|
||||||
# *TODO - Adapt this to support VC9
|
# *TODO - Adapt this to support VC9
|
||||||
if (MSVC80)
|
if (MSVC80)
|
||||||
@@ -435,6 +393,3 @@ add_custom_target(copy_win_libs ALL
|
|||||||
)
|
)
|
||||||
add_dependencies(copy_win_libs prepare)
|
add_dependencies(copy_win_libs prepare)
|
||||||
|
|
||||||
if(EXISTS ${internal_llkdu_path})
|
|
||||||
add_dependencies(copy_win_libs llkdu)
|
|
||||||
endif(EXISTS ${internal_llkdu_path})
|
|
||||||
|
|||||||
@@ -1 +1,18 @@
|
|||||||
set(CWDEBUG_LIBRARIES cwdebug)
|
include_directories (${CMAKE_SOURCE_DIR}/cwdebug)
|
||||||
|
|
||||||
|
set(cwdebug_SOURCE_FILES
|
||||||
|
${CMAKE_SOURCE_DIR}/cwdebug/debug.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
set(cwdebug_HEADER_FILES
|
||||||
|
${CMAKE_SOURCE_DIR}/cwdebug/cwdebug.h
|
||||||
|
${CMAKE_SOURCE_DIR}/cwdebug/sys.h
|
||||||
|
${CMAKE_SOURCE_DIR}/cwdebug/debug.h
|
||||||
|
${CMAKE_SOURCE_DIR}/cwdebug/debug_ostream_operators.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(${cwdebug_HEADER_FILES}
|
||||||
|
PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
|
||||||
|
list(APPEND cwdebug_SOURCE_FILES ${cwdebug_HEADER_FILES})
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
|
|
||||||
if (VIEWER AND WINDOWS)
|
if (WINDOWS)
|
||||||
find_path(DIRECTX_INCLUDE_DIR dxdiag.h
|
find_path(DIRECTX_INCLUDE_DIR dxdiag.h
|
||||||
"$ENV{DXSDK_DIR}/Include"
|
"$ENV{DXSDK_DIR}/Include"
|
||||||
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include"
|
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include"
|
||||||
@@ -43,4 +43,4 @@ if (VIEWER AND WINDOWS)
|
|||||||
message(FATAL_ERROR "Could not find DirectX SDK Libraries")
|
message(FATAL_ERROR "Could not find DirectX SDK Libraries")
|
||||||
endif (DIRECTX_LIBRARY_DIR)
|
endif (DIRECTX_LIBRARY_DIR)
|
||||||
|
|
||||||
endif (VIEWER AND WINDOWS)
|
endif (WINDOWS)
|
||||||
|
|||||||
@@ -2,57 +2,59 @@
|
|||||||
|
|
||||||
include(Linking)
|
include(Linking)
|
||||||
|
|
||||||
if(INSTALL_PROPRIETARY)
|
|
||||||
include(Prebuilt)
|
|
||||||
use_prebuilt_binary(fmodex)
|
|
||||||
endif(INSTALL_PROPRIETARY)
|
|
||||||
|
|
||||||
find_library(FMODEX_LIBRARY
|
|
||||||
NAMES fmodex fmodex_vc fmodexL_vc
|
|
||||||
PATHS
|
|
||||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}
|
|
||||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (NOT FMODEX_LIBRARY)
|
if (NOT FMODEX_LIBRARY)
|
||||||
set(FMODEX_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.")
|
set(FMODEX_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.")
|
||||||
if (FMODEX_SDK_DIR)
|
if (FMODEX_SDK_DIR)
|
||||||
find_library(FMODEX_LIBRARY
|
if(WORD_SIZE EQUAL 32)
|
||||||
fmodex fmodex_vc fmodexL_vc
|
find_library(FMODEX_LIBRARY
|
||||||
PATHS
|
fmodex_vc fmodexL_vc fmodex fmodexL
|
||||||
${FMODEX_SDK_DIR}/api/lib
|
PATHS
|
||||||
${FMODEX_SDK_DIR}/api
|
"${FMODEX_SDK_DIR}/api/lib"
|
||||||
${FMODEX_SDK_DIR}/lib
|
"${FMODEX_SDK_DIR}/api"
|
||||||
${FMODEX_SDK_DIR}
|
"${FMODEX_SDK_DIR}/lib"
|
||||||
)
|
"${FMODEX_SDK_DIR}"
|
||||||
|
)
|
||||||
|
elseif(WORD_SIZE EQUAL 64)
|
||||||
|
find_library(FMODEX_LIBRARY
|
||||||
|
fmodex64 fmodexL64
|
||||||
|
PATHS
|
||||||
|
"${FMODEX_SDK_DIR}/api/lib"
|
||||||
|
"${FMODEX_SDK_DIR}/api"
|
||||||
|
"${FMODEX_SDK_DIR}/lib"
|
||||||
|
"${FMODEX_SDK_DIR}"
|
||||||
|
)
|
||||||
|
endif(WORD_SIZE EQUAL 32)
|
||||||
endif(FMODEX_SDK_DIR)
|
endif(FMODEX_SDK_DIR)
|
||||||
if(WINDOWS AND NOT FMODEX_LIBRARY)
|
if(WINDOWS AND NOT FMODEX_LIBRARY)
|
||||||
set(FMODEX_PROG_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows")
|
set(FMODEX_PROG_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows")
|
||||||
find_library(FMODEX_LIBRARY
|
find_library(FMODEX_LIBRARY
|
||||||
fmodex_vc fmodexL_vc
|
fmodex_vc fmodexL_vc
|
||||||
PATHS
|
PATHS
|
||||||
${FMODEX_PROG_DIR}/api/lib
|
"${FMODEX_PROG_DIR}/api/lib"
|
||||||
${FMODEX_PROG_DIR}/api
|
"${FMODEX_PROG_DIR}/api"
|
||||||
${FMODEX_PROG_DIR}
|
"${FMODEX_PROG_DIR}"
|
||||||
)
|
)
|
||||||
if(FMODEX_LIBRARY)
|
if(FMODEX_LIBRARY)
|
||||||
message(STATUS "Found fmodex in ${FMODEX_PROG_DIR}")
|
message(STATUS "Found fmodex in ${FMODEX_PROG_DIR}")
|
||||||
set(FMODEX_SDK_DIR ${FMODEX_PROG_DIR})
|
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}")
|
||||||
set(FMODEX_SDK_DIR ${FMODEX_PROG_DIR} CACHE PATH "Path to the FMOD Ex SDK." FORCE)
|
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}" CACHE PATH "Path to the FMOD Ex SDK." FORCE)
|
||||||
endif(FMODEX_LIBRARY)
|
endif(FMODEX_LIBRARY)
|
||||||
endif(WINDOWS AND NOT FMODEX_LIBRARY)
|
endif(WINDOWS AND NOT FMODEX_LIBRARY)
|
||||||
endif (NOT FMODEX_LIBRARY)
|
endif (NOT FMODEX_LIBRARY)
|
||||||
|
|
||||||
find_path(FMODEX_INCLUDE_DIR fmod.h
|
find_path(FMODEX_INCLUDE_DIR fmod.hpp
|
||||||
${LIBS_PREBUILT_DIR}/include/fmodex
|
"${LIBS_PREBUILT_DIR}/include/fmodex"
|
||||||
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/fmodex
|
"${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/fmodex"
|
||||||
${FMODEX_SDK_DIR}/api/inc
|
"${FMODEX_SDK_DIR}/api/inc"
|
||||||
${FMODEX_SDK_DIR}/inc
|
"${FMODEX_SDK_DIR}/inc"
|
||||||
${FMODEX_SDK_DIR}
|
"${FMODEX_SDK_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(DARWIN)
|
||||||
|
set(FMODEX_ORIG_LIBRARY "${FMODEX_LIBRARY}")
|
||||||
|
set(FMODEX_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/libfmodex.dylib")
|
||||||
|
endif(DARWIN)
|
||||||
|
|
||||||
if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
||||||
set(FMODEX ON CACHE BOOL "Use closed source FMOD Ex sound library.")
|
set(FMODEX ON CACHE BOOL "Use closed source FMOD Ex sound library.")
|
||||||
else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
||||||
|
|||||||
31
indra/cmake/FindColladadom.cmake
Normal file
31
indra/cmake/FindColladadom.cmake
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
# - Find collada14dom
|
||||||
|
# Find the colladadom version 1.4 includes and library
|
||||||
|
# This module defines
|
||||||
|
# COLLADADOM_FOUND, System has libcollada14dom.so.
|
||||||
|
# COLLADADOM_INCLUDE_DIRS - The collada include directories.
|
||||||
|
# COLLADADOM_LIBRARIES - The libraries needed to use libcollada14dom.
|
||||||
|
# COLLADADOM_DEFINITIONS - Compiler switches required for using libcollada14dom.
|
||||||
|
|
||||||
|
FIND_PACKAGE(PkgConfig)
|
||||||
|
PKG_CHECK_MODULES(PC_COLLADADOM collada)
|
||||||
|
SET(COLLADADOM_DEFINITIONS ${PC_COLLADADOM_CFLAGS_OTHER})
|
||||||
|
|
||||||
|
FIND_PATH(COLLADADOM_INCLUDE_DIR dae.h
|
||||||
|
HINTS ${PC_COLLADADOM_INCLUDE_DIR} ${PC_COLLADADOM_INCLUDE_DIRS}
|
||||||
|
PATH_SUFFIXES collada)
|
||||||
|
|
||||||
|
FIND_LIBRARY(COLLADADOM_LIBRARY
|
||||||
|
NAMES libcollada14dom.so
|
||||||
|
HINTS ${PC_COLLADADOM_LIBDIR} ${PC_COLLADADOM_LIBRARY_DIRS}
|
||||||
|
PATHS /usr/lib /usr/local/lib)
|
||||||
|
|
||||||
|
SET(COLLADADOM_LIBRARIES ${COLLADADOM_LIBRARY})
|
||||||
|
SET(COLLADADOM_INCLUDE_DIRS ${COLLADADOM_INCLUDE_DIR} ${COLLADADOM_INCLUDE_DIR}/1.4)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(COLLADADOM DEFAULT_MSG
|
||||||
|
COLLADADOM_LIBRARY COLLADADOM_INCLUDE_DIR)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(COLLADADOM_LIBRARY COLLADADOM_INCLUDE_DIR)
|
||||||
32
indra/cmake/FindGLOD.cmake
Normal file
32
indra/cmake/FindGLOD.cmake
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
# - Find GLOD
|
||||||
|
# Find the GLOD includes and library
|
||||||
|
# This module defines
|
||||||
|
# GLOD_FOUND, System has libglod.so.
|
||||||
|
# GLOD_INCLUDE_DIRS - The GLOD include directories.
|
||||||
|
# GLOD_LIBRARIES - The libraries needed to use libglod.
|
||||||
|
# GLOD_DEFINITIONS - Compiler switches required for using libglod.
|
||||||
|
|
||||||
|
FIND_PACKAGE(PkgConfig)
|
||||||
|
PKG_CHECK_MODULES(PC_GLOD glod)
|
||||||
|
SET(GLOD_DEFINITIONS ${PC_GLOD_CFLAGS_OTHER})
|
||||||
|
|
||||||
|
FIND_PATH(GLOD_INCLUDE_DIR glod/glod.h
|
||||||
|
HINTS ${PC_GLOD_INCLUDE_DIR} ${PC_GLOD_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_LIBRARY(GLOD_LIBRARY
|
||||||
|
NAMES libGLOD.so
|
||||||
|
HINTS ${PC_GLOD_LIBDIR} ${PC_GLOD_LIBRARY_DIRS}
|
||||||
|
PATHS /usr/lib /usr/local/lib)
|
||||||
|
|
||||||
|
SET(GLOD_LIBRARIES ${GLOD_LIBRARY})
|
||||||
|
SET(GLOD_INCLUDE_DIRS ${GLOD_INCLUDE_DIR})
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLOD DEFAULT_MSG
|
||||||
|
GLOD_LIBRARY GLOD_INCLUDE_DIR)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(GLOD_LIBRARY GLOD_INCLUDE_DIR)
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@ FIND_PATH(HUNSPELL_INCLUDE_DIR hunspell.hxx
|
|||||||
/usr/include
|
/usr/include
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(HUNSPELL_NAMES ${HUNSPELL_NAMES} hunspell hunspell-1.2)
|
SET(HUNSPELL_NAMES ${HUNSPELL_NAMES} hunspell hunspell-1.2 hunspell-1.3)
|
||||||
FIND_LIBRARY(HUNSPELL_LIBRARY
|
FIND_LIBRARY(HUNSPELL_LIBRARY
|
||||||
NAMES ${HUNSPELL_NAMES}
|
NAMES ${HUNSPELL_NAMES}
|
||||||
PATHS /usr/lib /usr/local/lib
|
PATHS /usr/lib /usr/local/lib
|
||||||
|
|||||||
@@ -3,16 +3,18 @@
|
|||||||
# - Find JSONCpp
|
# - Find JSONCpp
|
||||||
# Find the JSONCpp includes and library
|
# Find the JSONCpp includes and library
|
||||||
# This module defines
|
# This module defines
|
||||||
# JSONCPP_INCLUDE_DIR, where to find json.h, etc.
|
# JSONCPP_FOUND, System has libjsoncpp.
|
||||||
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
|
# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories.
|
||||||
# JSONCPP_FOUND, If false, do not try to use jsoncpp.
|
# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp.
|
||||||
# also defined, but not for general use are
|
# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp.
|
||||||
# JSONCPP_LIBRARY, where to find the jsoncpp library.
|
|
||||||
|
|
||||||
FIND_PATH(JSONCPP_INCLUDE_DIR json/json.h
|
FIND_PACKAGE(PkgConfig)
|
||||||
/usr/local/include
|
PKG_CHECK_MODULES(PC_JSONCPP jsoncpp)
|
||||||
/usr/include
|
SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER})
|
||||||
)
|
|
||||||
|
FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h
|
||||||
|
HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS}
|
||||||
|
PATH_SUFFIXES jsoncpp)
|
||||||
|
|
||||||
# Get the GCC compiler version
|
# Get the GCC compiler version
|
||||||
EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
|
EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
|
||||||
@@ -22,39 +24,16 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Try to find a library that was compiled with the same compiler version as we currently use.
|
# Try to find a library that was compiled with the same compiler version as we currently use.
|
||||||
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so)
|
|
||||||
IF (STANDALONE)
|
|
||||||
# On standalone, assume that the system installed library was compiled with the used compiler.
|
|
||||||
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so)
|
|
||||||
ENDIF (STANDALONE)
|
|
||||||
FIND_LIBRARY(JSONCPP_LIBRARY
|
FIND_LIBRARY(JSONCPP_LIBRARY
|
||||||
NAMES ${JSONCPP_NAMES}
|
NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so
|
||||||
PATHS /usr/lib /usr/local/lib
|
HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS}
|
||||||
)
|
PATHS /usr/lib /usr/local/lib)
|
||||||
|
|
||||||
IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
|
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
|
||||||
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
|
SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR})
|
||||||
SET(JSONCPP_FOUND "YES")
|
|
||||||
ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
|
|
||||||
SET(JSONCPP_FOUND "NO")
|
|
||||||
ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
|
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG
|
||||||
|
JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
|
||||||
|
|
||||||
IF (JSONCPP_FOUND)
|
MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
|
||||||
IF (NOT JSONCPP_FIND_QUIETLY)
|
|
||||||
MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
|
|
||||||
ENDIF (NOT JSONCPP_FIND_QUIETLY)
|
|
||||||
ELSE (JSONCPP_FOUND)
|
|
||||||
IF (JSONCPP_FIND_REQUIRED)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find JSONCpp library")
|
|
||||||
ENDIF (JSONCPP_FIND_REQUIRED)
|
|
||||||
ENDIF (JSONCPP_FOUND)
|
|
||||||
|
|
||||||
# Deprecated declarations.
|
|
||||||
SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} )
|
|
||||||
GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
|
||||||
JSONCPP_LIBRARY
|
|
||||||
JSONCPP_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
#Find the windows manifest tool.
|
|
||||||
if (MSVC80)
|
|
||||||
FIND_PROGRAM(HAVE_MANIFEST_TOOL NAMES mt
|
|
||||||
PATHS
|
|
||||||
"$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/VC/bin"
|
|
||||||
"$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/Common7/Tools/Bin"
|
|
||||||
"$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/SDK/v2.0/Bin")
|
|
||||||
IF(HAVE_MANIFEST_TOOL)
|
|
||||||
MESSAGE(STATUS "Found Mainfest Tool. Embedding custom manifests.")
|
|
||||||
ELSE(HAVE_MANIFEST_TOOL)
|
|
||||||
MESSAGE(FATAL_ERROR "Manifest tool, mt.exe, can't be found.")
|
|
||||||
ENDIF(HAVE_MANIFEST_TOOL)
|
|
||||||
|
|
||||||
STRING(REPLACE "/MANIFEST " "/MANIFEST:NO" CMAKE_EXE_LINKER_FLAGS
|
|
||||||
${CMAKE_EXE_LINKER_FLAGS})
|
|
||||||
|
|
||||||
endif (MSVC80)
|
|
||||||
13
indra/cmake/GLOD.cmake
Normal file
13
indra/cmake/GLOD.cmake
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
include(Prebuilt)
|
||||||
|
|
||||||
|
set(GLOD_FIND_QUIETLY OFF)
|
||||||
|
set(GLOD_FIND_REQUIRED ON)
|
||||||
|
|
||||||
|
if (STANDALONE)
|
||||||
|
include(FindGLOD)
|
||||||
|
else (STANDALONE)
|
||||||
|
use_prebuilt_binary(GLOD)
|
||||||
|
set(GLOD_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||||
|
set(GLOD_LIBRARIES glod)
|
||||||
|
endif (STANDALONE)
|
||||||
@@ -1,16 +1,20 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
include(Prebuilt)
|
include(Prebuilt)
|
||||||
|
|
||||||
|
if(WORD_SIZE EQUAL 64)
|
||||||
|
set(DISABLE_TCMALLOC TRUE)
|
||||||
|
endif(WORD_SIZE EQUAL 64)
|
||||||
|
|
||||||
if (STANDALONE)
|
if (STANDALONE)
|
||||||
include(FindGooglePerfTools)
|
include(FindGooglePerfTools)
|
||||||
else (STANDALONE)
|
else (STANDALONE)
|
||||||
if (LINUX OR WINDOWS)
|
if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||||
use_prebuilt_binary(gperftools)
|
use_prebuilt_binary(gperftools)
|
||||||
endif (LINUX OR WINDOWS)
|
endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
|
||||||
if (WINDOWS)
|
if (WINDOWS AND NOT DISABLE_TCMALLOC)
|
||||||
set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib)
|
set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib)
|
||||||
set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"")
|
set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"")
|
||||||
endif (WINDOWS)
|
endif (WINDOWS AND NOT DISABLE_TCMALLOC)
|
||||||
if (LINUX)
|
if (LINUX)
|
||||||
if(USE_GOOGLE_PERFTOOLS)
|
if(USE_GOOGLE_PERFTOOLS)
|
||||||
set(TCMALLOC_LIBRARIES tcmalloc)
|
set(TCMALLOC_LIBRARIES tcmalloc)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ if (STANDALONE)
|
|||||||
else (STANDALONE)
|
else (STANDALONE)
|
||||||
use_prebuilt_binary(hunspell)
|
use_prebuilt_binary(hunspell)
|
||||||
|
|
||||||
set(HUNSPELL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/hunspell)
|
set(HUNSPELL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/hunspell)
|
||||||
|
|
||||||
if (LINUX OR DARWIN)
|
if (LINUX OR DARWIN)
|
||||||
set(HUNSPELL_LIBRARY hunspell-1.3)
|
set(HUNSPELL_LIBRARY hunspell-1.3)
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ else (STANDALONE)
|
|||||||
set(JPEG_LIBRARIES jpeg)
|
set(JPEG_LIBRARIES jpeg)
|
||||||
elseif (DARWIN)
|
elseif (DARWIN)
|
||||||
set(JPEG_LIBRARIES
|
set(JPEG_LIBRARIES
|
||||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/liblljpeg.a
|
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a
|
||||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/liblljpeg.a
|
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libjpeg.a
|
||||||
)
|
)
|
||||||
elseif (WINDOWS)
|
elseif (WINDOWS)
|
||||||
set(JPEG_LIBRARIES jpeglib)
|
set(JPEG_LIBRARIES jpeglib)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
include(Prebuilt)
|
include(Prebuilt)
|
||||||
|
|
||||||
set(JSONCPP_FIND_QUIETLY ON)
|
set(JSONCPP_FIND_QUIETLY OFF)
|
||||||
set(JSONCPP_FIND_REQUIRED ON)
|
set(JSONCPP_FIND_REQUIRED ON)
|
||||||
|
|
||||||
if (STANDALONE)
|
if (STANDALONE)
|
||||||
@@ -14,9 +14,9 @@ else (STANDALONE)
|
|||||||
debug json_vc${MSVC_SUFFIX}d
|
debug json_vc${MSVC_SUFFIX}d
|
||||||
optimized json_vc${MSVC_SUFFIX})
|
optimized json_vc${MSVC_SUFFIX})
|
||||||
elseif (DARWIN)
|
elseif (DARWIN)
|
||||||
set(JSONCPP_LIBRARIES json_mac-universal-gcc_libmt)
|
set(JSONCPP_LIBRARIES json_linux-gcc-4.0.1_libmt)
|
||||||
elseif (LINUX)
|
elseif (LINUX)
|
||||||
set(JSONCPP_LIBRARIES jsoncpp)
|
set(JSONCPP_LIBRARIES jsoncpp)
|
||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
set(JSONCPP_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/jsoncpp)
|
set(JSONCPP_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/jsoncpp)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE)
|
||||||
|
|||||||
11
indra/cmake/LLAppearance.cmake
Normal file
11
indra/cmake/LLAppearance.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
include(Variables)
|
||||||
|
|
||||||
|
set(LLAPPEARANCE_INCLUDE_DIRS
|
||||||
|
${LIBS_OPEN_DIR}/llappearance
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LLAPPEARANCE_LIBRARIES llappearance)
|
||||||
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# -*- cmake -*-
|
|
||||||
|
|
||||||
include(MySQL)
|
|
||||||
|
|
||||||
set(LLDATABASE_INCLUDE_DIRS
|
|
||||||
${LIBS_SERVER_DIR}/lldatabase
|
|
||||||
${MYSQL_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
set(LLDATABASE_LIBRARIES lldatabase)
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# -*- cmake -*-
|
|
||||||
include(Prebuilt)
|
|
||||||
|
|
||||||
if (NOT STANDALONE AND EXISTS ${LIBS_CLOSED_DIR}/llkdu)
|
|
||||||
use_prebuilt_binary(kdu)
|
|
||||||
if (WINDOWS)
|
|
||||||
set(KDU_LIBRARY debug kdu_cored optimized kdu_core)
|
|
||||||
else (WINDOWS)
|
|
||||||
set(KDU_LIBRARY kdu)
|
|
||||||
endif (WINDOWS)
|
|
||||||
|
|
||||||
set(KDU_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
|
||||||
|
|
||||||
set(LLKDU_LIBRARY llkdu)
|
|
||||||
set(LLKDU_STATIC_LIBRARY llkdu_static)
|
|
||||||
set(LLKDU_LIBRARIES ${LLKDU_LIBRARY})
|
|
||||||
set(LLKDU_STATIC_LIBRARIES ${LLKDU_STATIC_LIBRARY})
|
|
||||||
endif (NOT STANDALONE AND EXISTS ${LIBS_CLOSED_DIR}/llkdu)
|
|
||||||
@@ -4,12 +4,14 @@ include(CARes)
|
|||||||
include(CURL)
|
include(CURL)
|
||||||
include(OpenSSL)
|
include(OpenSSL)
|
||||||
include(XmlRpcEpi)
|
include(XmlRpcEpi)
|
||||||
|
include(AIStateMachine)
|
||||||
|
|
||||||
set(LLMESSAGE_INCLUDE_DIRS
|
set(LLMESSAGE_INCLUDE_DIRS
|
||||||
${LIBS_OPEN_DIR}/llmessage
|
${LIBS_OPEN_DIR}/llmessage
|
||||||
${CARES_INCLUDE_DIRS}
|
${CARES_INCLUDE_DIRS}
|
||||||
${CURL_INCLUDE_DIRS}
|
${CURL_INCLUDE_DIRS}
|
||||||
${OPENSSL_INCLUDE_DIRS}
|
${OPENSSL_INCLUDE_DIRS}
|
||||||
|
${AISTATEMACHINE_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LLMESSAGE_LIBRARIES llmessage)
|
set(LLMESSAGE_LIBRARIES llmessage aistatemachine)
|
||||||
|
|||||||
7
indra/cmake/LLPhysicsExtensions.cmake
Normal file
7
indra/cmake/LLPhysicsExtensions.cmake
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
set(LLPHYSICSEXTENSIONS_LIBRARIES nd_hacdConvexDecomposition hacd nd_Pathing )
|
||||||
|
set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_OPEN_DIR}/libndhacd ${LIBS_OPEN_DIR}/libpathing)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,7 +1,22 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
|
|
||||||
set(LLPRIMITIVE_INCLUDE_DIRS
|
include(Colladadom)
|
||||||
${LIBS_OPEN_DIR}/llprimitive
|
|
||||||
)
|
set(LLPRIMITIVE_INCLUDE_DIRS
|
||||||
|
${LIBS_OPEN_DIR}/llprimitive
|
||||||
|
${COLLADADOM_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (WINDOWS)
|
||||||
|
set(LLPRIMITIVE_LIBRARIES
|
||||||
|
debug llprimitive
|
||||||
|
optimized llprimitive
|
||||||
|
${COLLADADOM_LIBRARIES}
|
||||||
|
)
|
||||||
|
else (WINDOWS)
|
||||||
|
set(LLPRIMITIVE_LIBRARIES
|
||||||
|
llprimitive
|
||||||
|
${COLLADADOM_LIBRARIES}
|
||||||
|
)
|
||||||
|
endif (WINDOWS)
|
||||||
|
|
||||||
set(LLPRIMITIVE_LIBRARIES llprimitive)
|
|
||||||
|
|||||||
11
indra/cmake/LLQtWebkit.cmake
Normal file
11
indra/cmake/LLQtWebkit.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
if (STANDALONE)
|
||||||
|
set(LLQTWEBKIT_INCLUDE_DIR
|
||||||
|
${LIBS_OPEN_DIR}/llqtwebkit
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LLQTWEBKIT_LIBRARY
|
||||||
|
llqtwebkit
|
||||||
|
)
|
||||||
|
endif (STANDALONE)
|
||||||
@@ -6,27 +6,7 @@ set(LLRENDER_INCLUDE_DIRS
|
|||||||
${LIBS_OPEN_DIR}/llrender
|
${LIBS_OPEN_DIR}/llrender
|
||||||
)
|
)
|
||||||
|
|
||||||
if (SERVER AND LINUX)
|
|
||||||
set(LLRENDER_LIBRARIES
|
|
||||||
llrenderheadless
|
|
||||||
)
|
|
||||||
else (SERVER AND LINUX)
|
|
||||||
set(LLRENDER_LIBRARIES
|
set(LLRENDER_LIBRARIES
|
||||||
llrender
|
llrender
|
||||||
)
|
)
|
||||||
endif (SERVER AND LINUX)
|
|
||||||
|
|
||||||
# mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set
|
|
||||||
# differently for different object files.
|
|
||||||
macro (copy_server_sources )
|
|
||||||
foreach (PREFIX ${ARGV})
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
|
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
|
|
||||||
)
|
|
||||||
list(APPEND server_SOURCE_FILES ${PREFIX}_server.cpp)
|
|
||||||
endforeach (PREFIX ${_copied_SOURCES})
|
|
||||||
endmacro (copy_server_sources _copied_SOURCES)
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
# -*- cmake -*-
|
|
||||||
|
|
||||||
set(LLSCENE_INCLUDE_DIRS
|
|
||||||
${LIBS_SERVER_DIR}/llscene
|
|
||||||
)
|
|
||||||
|
|
||||||
set(LLSCENE_LIBRARIES llscene)
|
|
||||||
@@ -8,5 +8,5 @@ set(LLVFS_INCLUDE_DIRS
|
|||||||
|
|
||||||
set(LLVFS_LIBRARIES
|
set(LLVFS_LIBRARIES
|
||||||
llvfs
|
llvfs
|
||||||
${BOOST_REGEX_LIBRARY}
|
${Boost_REGEX_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ else (STANDALONE)
|
|||||||
use_prebuilt_binary(SDL)
|
use_prebuilt_binary(SDL)
|
||||||
set (SDL_FOUND TRUE)
|
set (SDL_FOUND TRUE)
|
||||||
set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR})
|
set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR})
|
||||||
set (SDL_LIBRARY SDL directfb fusion direct)
|
if(WORD_SIZE EQUAL 64)
|
||||||
|
set (SDL_LIBRARY SDL)
|
||||||
|
else(WORD_SIZE EQUAL 64)
|
||||||
|
set (SDL_LIBRARY SDL directfb fusion direct)
|
||||||
|
endif(WORD_SIZE EQUAL 64)
|
||||||
endif (LINUX)
|
endif (LINUX)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE)
|
||||||
|
|
||||||
@@ -32,17 +36,12 @@ set(LLWINDOW_INCLUDE_DIRS
|
|||||||
${LIBS_OPEN_DIR}/llwindow
|
${LIBS_OPEN_DIR}/llwindow
|
||||||
)
|
)
|
||||||
|
|
||||||
if (SERVER AND LINUX)
|
set(LLWINDOW_LIBRARIES
|
||||||
set(LLWINDOW_LIBRARIES
|
llwindow
|
||||||
llwindowheadless
|
)
|
||||||
)
|
|
||||||
else (SERVER AND LINUX)
|
if (WINDOWS)
|
||||||
set(LLWINDOW_LIBRARIES
|
list(APPEND LLWINDOW_LIBRARIES
|
||||||
llwindow
|
comdlg32
|
||||||
)
|
)
|
||||||
if (WINDOWS)
|
endif (WINDOWS)
|
||||||
list(APPEND LLWINDOW_LIBRARIES
|
|
||||||
comdlg32
|
|
||||||
)
|
|
||||||
endif (WINDOWS)
|
|
||||||
endif (SERVER AND LINUX)
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
# -*- cmake -*-
|
|
||||||
|
|
||||||
set(LLXUIXML_INCLUDE_DIRS
|
|
||||||
${LIBS_OPEN_DIR}/llxuixml
|
|
||||||
)
|
|
||||||
|
|
||||||
set(LLXUIXML_LIBRARIES llxuixml)
|
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
|
if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
|
||||||
|
|
||||||
|
include(Variables)
|
||||||
|
|
||||||
if (NOT STANDALONE)
|
if (NOT STANDALONE)
|
||||||
if (WINDOWS)
|
if (WINDOWS)
|
||||||
@@ -10,9 +14,9 @@ if (NOT STANDALONE)
|
|||||||
set(ARCH_PREBUILT_DIRS_RELEASE ${ARCH_PREBUILT_DIRS})
|
set(ARCH_PREBUILT_DIRS_RELEASE ${ARCH_PREBUILT_DIRS})
|
||||||
set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS})
|
set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS})
|
||||||
elseif (DARWIN)
|
elseif (DARWIN)
|
||||||
set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib_release)
|
set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib)
|
||||||
set(ARCH_PREBUILT_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
|
set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release)
|
||||||
set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS_RELEASE})
|
set(ARCH_PREBUILT_DIRS_DEBUG ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/debug)
|
||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
endif (NOT STANDALONE)
|
endif (NOT STANDALONE)
|
||||||
|
|
||||||
@@ -45,3 +49,5 @@ else (WINDOWS)
|
|||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
|
|
||||||
mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
|
mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
|
||||||
|
|
||||||
|
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
|||||||
@@ -3,8 +3,5 @@ include(Prebuilt)
|
|||||||
|
|
||||||
if (NOT (STANDALONE OR DARWIN))
|
if (NOT (STANDALONE OR DARWIN))
|
||||||
use_prebuilt_binary(glext)
|
use_prebuilt_binary(glext)
|
||||||
# possible glh_linear should have its own .cmake file instead
|
|
||||||
#use_prebuilt_binary(glh_linear)
|
|
||||||
# actually... not any longer, it's now in git -SG
|
|
||||||
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||||
endif ()
|
endif (NOT (STANDALONE OR DARWIN))
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ include(Prebuilt)
|
|||||||
set(OpenSSL_FIND_QUIETLY ON)
|
set(OpenSSL_FIND_QUIETLY ON)
|
||||||
set(OpenSSL_FIND_REQUIRED ON)
|
set(OpenSSL_FIND_REQUIRED ON)
|
||||||
|
|
||||||
if (STANDALONE)
|
if (STANDALONE OR USE_SYSTEM_OPENSSL)
|
||||||
include(FindOpenSSL)
|
include(FindOpenSSL)
|
||||||
else (STANDALONE)
|
else (STANDALONE OR USE_SYSTEM_OPENSSL)
|
||||||
use_prebuilt_binary(openSSL)
|
use_prebuilt_binary(openSSL)
|
||||||
if (WINDOWS)
|
if (WINDOWS)
|
||||||
set(OPENSSL_LIBRARIES ssleay32 libeay32)
|
set(OPENSSL_LIBRARIES ssleay32 libeay32)
|
||||||
@@ -14,10 +14,8 @@ else (STANDALONE)
|
|||||||
set(OPENSSL_LIBRARIES ssl)
|
set(OPENSSL_LIBRARIES ssl)
|
||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE OR USE_SYSTEM_OPENSSL)
|
||||||
|
|
||||||
if (LINUX)
|
if (LINUX OR DARWIN)
|
||||||
set(CRYPTO_LIBRARIES crypto)
|
set(CRYPTO_LIBRARIES crypto)
|
||||||
elseif (DARWIN)
|
endif (LINUX OR DARWIN)
|
||||||
set(CRYPTO_LIBRARIES llcrypto)
|
|
||||||
endif (LINUX)
|
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ else (STANDALONE)
|
|||||||
else(LINUX)
|
else(LINUX)
|
||||||
set(PNG_LIBRARIES png15)
|
set(PNG_LIBRARIES png15)
|
||||||
endif()
|
endif()
|
||||||
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libpng15)
|
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/)
|
||||||
endif (STANDALONE)
|
endif (STANDALONE)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
|
||||||
|
|
||||||
macro (use_prebuilt_binary _binary)
|
macro (use_prebuilt_binary _binary)
|
||||||
if(NOT STANDALONE)
|
if(NOT STANDALONE)
|
||||||
get_property(PREBUILT_PACKAGES TARGET prepare PROPERTY PREBUILT)
|
get_property(PREBUILT_PACKAGES TARGET prepare PROPERTY PREBUILT)
|
||||||
@@ -9,3 +12,5 @@ macro (use_prebuilt_binary _binary)
|
|||||||
endif(_index LESS 0)
|
endif(_index LESS 0)
|
||||||
endif(NOT STANDALONE)
|
endif(NOT STANDALONE)
|
||||||
endmacro (use_prebuilt_binary _binary)
|
endmacro (use_prebuilt_binary _binary)
|
||||||
|
|
||||||
|
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
|||||||
12
indra/cmake/Qt4.cmake
Normal file
12
indra/cmake/Qt4.cmake
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
include(Prebuilt)
|
||||||
|
|
||||||
|
if (STANDALONE)
|
||||||
|
set(Qt4_FIND_REQUIRED ON)
|
||||||
|
|
||||||
|
include(FindQt4)
|
||||||
|
|
||||||
|
find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
|
||||||
|
include(${QT_USE_FILE})
|
||||||
|
add_definitions(${QT_DEFINITIONS})
|
||||||
|
endif (STANDALONE)
|
||||||
4
indra/cmake/StateMachine.cmake
Normal file
4
indra/cmake/StateMachine.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# -*- cmake -*-
|
||||||
|
|
||||||
|
set(STATEMACHINE_INCLUDE_DIRS statemachine)
|
||||||
|
set(STATEMACHINE_LIBRARIES statemachine)
|
||||||
@@ -8,40 +8,32 @@
|
|||||||
# DARWIN - Mac OS X
|
# DARWIN - Mac OS X
|
||||||
# LINUX - Linux
|
# LINUX - Linux
|
||||||
# WINDOWS - Windows
|
# WINDOWS - Windows
|
||||||
#
|
|
||||||
# What to build:
|
|
||||||
#
|
|
||||||
# VIEWER - viewer and other viewer-side components
|
|
||||||
# SERVER - simulator and other server-side bits
|
|
||||||
|
|
||||||
|
|
||||||
# Relative and absolute paths to subtrees.
|
# Relative and absolute paths to subtrees.
|
||||||
|
|
||||||
|
if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
|
||||||
|
|
||||||
|
if(NOT DEFINED COMMON_CMAKE_DIR)
|
||||||
|
set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
endif(NOT DEFINED COMMON_CMAKE_DIR)
|
||||||
|
|
||||||
set(LIBS_CLOSED_PREFIX)
|
set(LIBS_CLOSED_PREFIX)
|
||||||
set(LIBS_OPEN_PREFIX)
|
set(LIBS_OPEN_PREFIX)
|
||||||
set(LIBS_SERVER_PREFIX)
|
|
||||||
set(SCRIPTS_PREFIX ../scripts)
|
set(SCRIPTS_PREFIX ../scripts)
|
||||||
set(SERVER_PREFIX)
|
|
||||||
set(VIEWER_PREFIX)
|
set(VIEWER_PREFIX)
|
||||||
|
|
||||||
set(LIBS_CLOSED_DIR ${CMAKE_SOURCE_DIR}/${LIBS_CLOSED_PREFIX})
|
set(LIBS_CLOSED_DIR ${CMAKE_SOURCE_DIR}/${LIBS_CLOSED_PREFIX})
|
||||||
set(LIBS_OPEN_DIR ${CMAKE_SOURCE_DIR}/${LIBS_OPEN_PREFIX})
|
set(LIBS_OPEN_DIR ${CMAKE_SOURCE_DIR}/${LIBS_OPEN_PREFIX})
|
||||||
set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
|
|
||||||
set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
|
set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
|
||||||
set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
|
|
||||||
set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
|
set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
|
||||||
|
set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)")
|
||||||
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)")
|
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)")
|
||||||
set(VISTA_ICON OFF CACHE BOOL "Allow vista icon with pre 2008 Visual Studio IDEs. (Assumes replacement old rcdll.dll with new rcdll.dll from win sdk 7.0 or later)")
|
|
||||||
|
|
||||||
set(LIBS_PREBUILT_DIR ${CMAKE_SOURCE_DIR}/../libraries CACHE PATH
|
set(LIBS_PREBUILT_DIR ${CMAKE_SOURCE_DIR}/../libraries CACHE PATH
|
||||||
"Location of prebuilt libraries.")
|
"Location of prebuilt libraries.")
|
||||||
|
|
||||||
if (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
|
|
||||||
# We use this as a marker that you can try to use the proprietary libraries.
|
|
||||||
set(INSTALL_PROPRIETARY ON CACHE BOOL "Install proprietary binaries")
|
|
||||||
endif (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)
|
|
||||||
|
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
set(WINDOWS ON BOOL FORCE)
|
set(WINDOWS ON BOOL FORCE)
|
||||||
set(ARCH i686)
|
set(ARCH i686)
|
||||||
@@ -69,6 +61,29 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||||||
endif(CMAKE_SIZEOF_VOID_P MATCHES 4)
|
endif(CMAKE_SIZEOF_VOID_P MATCHES 4)
|
||||||
endif (WORD_SIZE EQUAL 32)
|
endif (WORD_SIZE EQUAL 32)
|
||||||
|
|
||||||
|
if (NOT STANDALONE AND MULTIARCH_HACK)
|
||||||
|
if (WORD_SIZE EQUAL 32)
|
||||||
|
set(DEB_ARCHITECTURE i386)
|
||||||
|
set(FIND_LIBRARY_USE_LIB64_PATHS OFF)
|
||||||
|
set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib32 ${CMAKE_SYSTEM_LIBRARY_PATH})
|
||||||
|
else (WORD_SIZE EQUAL 32)
|
||||||
|
set(DEB_ARCHITECTURE amd64)
|
||||||
|
set(FIND_LIBRARY_USE_LIB64_PATHS ON)
|
||||||
|
endif (WORD_SIZE EQUAL 32)
|
||||||
|
|
||||||
|
execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH
|
||||||
|
RESULT_VARIABLE DPKG_RESULT
|
||||||
|
OUTPUT_VARIABLE DPKG_ARCH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||||
|
#message (STATUS "DPKG_RESULT ${DPKG_RESULT}, DPKG_ARCH ${DPKG_ARCH}")
|
||||||
|
if (DPKG_RESULT EQUAL 0)
|
||||||
|
set(CMAKE_LIBRARY_ARCHITECTURE ${DPKG_ARCH})
|
||||||
|
set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH})
|
||||||
|
endif (DPKG_RESULT EQUAL 0)
|
||||||
|
|
||||||
|
include(ConfigurePkgConfig)
|
||||||
|
endif (NOT STANDALONE AND MULTIARCH_HACK)
|
||||||
|
|
||||||
set(LL_ARCH ${ARCH}_linux)
|
set(LL_ARCH ${ARCH}_linux)
|
||||||
set(LL_ARCH_DIR ${ARCH}-linux)
|
set(LL_ARCH_DIR ${ARCH}-linux)
|
||||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
@@ -76,40 +91,33 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
set(DARWIN 1)
|
set(DARWIN 1)
|
||||||
|
|
||||||
#SDK Compiler and Deployment targets for XCode
|
if(${CMAKE_GENERATOR} MATCHES Xcode)
|
||||||
if (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
#SDK Compiler and Deployment targets for XCode
|
||||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
|
if (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||||
set(CMAKE_XCODE_ATTIBUTE_GCC_VERSION "4.2")
|
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
|
||||||
else (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
||||||
|
else (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||||
|
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk)
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||||
|
endif (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
||||||
|
else(${CMAKE_GENERATOR} MATCHES Xcode)
|
||||||
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk)
|
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk)
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||||
endif (${XCODE_VERSION} VERSION_LESS 4.0.0)
|
endif(${CMAKE_GENERATOR} MATCHES Xcode)
|
||||||
|
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
|
||||||
|
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
|
||||||
|
|
||||||
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
|
|
||||||
# -DCMAKE_OSX_ARCHITECTURES:STRING='i386;ppc'
|
|
||||||
# Build only for i386 by default, system default on MacOSX 10.6 is x86_64
|
# Build only for i386 by default, system default on MacOSX 10.6 is x86_64
|
||||||
if (NOT CMAKE_OSX_ARCHITECTURES)
|
set(CMAKE_OSX_ARCHITECTURES i386)
|
||||||
set(CMAKE_OSX_ARCHITECTURES i386)
|
set(ARCH i386)
|
||||||
endif (NOT CMAKE_OSX_ARCHITECTURES)
|
set(WORD_SIZE 32)
|
||||||
|
|
||||||
if (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
|
||||||
set(ARCH universal)
|
|
||||||
else (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
|
||||||
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc")
|
|
||||||
set(ARCH ppc)
|
|
||||||
else (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc")
|
|
||||||
set(ARCH i386)
|
|
||||||
endif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc")
|
|
||||||
endif (CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc")
|
|
||||||
|
|
||||||
set(LL_ARCH ${ARCH}_darwin)
|
set(LL_ARCH ${ARCH}_darwin)
|
||||||
set(LL_ARCH_DIR universal-darwin)
|
set(LL_ARCH_DIR universal-darwin)
|
||||||
set(WORD_SIZE 32)
|
|
||||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
|
|
||||||
|
|
||||||
if (WINDOWS)
|
if (WINDOWS)
|
||||||
set(PREBUILT_TYPE windows)
|
set(PREBUILT_TYPE windows)
|
||||||
elseif(DARWIN)
|
elseif(DARWIN)
|
||||||
@@ -120,11 +128,9 @@ elseif(LINUX AND WORD_SIZE EQUAL 64)
|
|||||||
set(PREBUILT_TYPE linux64)
|
set(PREBUILT_TYPE linux64)
|
||||||
endif(WINDOWS)
|
endif(WINDOWS)
|
||||||
|
|
||||||
|
|
||||||
# Default deploy grid
|
# Default deploy grid
|
||||||
set(GRID agni CACHE STRING "Target Grid")
|
set(GRID agni CACHE STRING "Target Grid")
|
||||||
|
|
||||||
set(VIEWER ON CACHE BOOL "Build Second Life viewer.")
|
|
||||||
set(VIEWER_CHANNEL "Singularity" CACHE STRING "Viewer Channel Name")
|
set(VIEWER_CHANNEL "Singularity" CACHE STRING "Viewer Channel Name")
|
||||||
set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
|
set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
|
||||||
set(VIEWER_BRANDING_ID "singularity" CACHE STRING "Viewer branding id (currently secondlife|snowglobe)")
|
set(VIEWER_BRANDING_ID "singularity" CACHE STRING "Viewer branding id (currently secondlife|snowglobe)")
|
||||||
@@ -135,17 +141,6 @@ set(VIEWER_BRANDING_NAME_CAMELCASE "Singularity")
|
|||||||
|
|
||||||
set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
|
set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
|
||||||
|
|
||||||
if (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
|
|
||||||
set(SERVER ON CACHE BOOL "Build Second Life server software.")
|
|
||||||
endif (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
|
|
||||||
|
|
||||||
if (LINUX AND SERVER AND VIEWER)
|
|
||||||
MESSAGE(FATAL_ERROR "
|
|
||||||
The indra source does not currently support building SERVER and VIEWER at the same time.
|
|
||||||
Please set one of these values to OFF in your CMake cache file.
|
|
||||||
(either by running ccmake or by editing CMakeCache.txt by hand)
|
|
||||||
For more information, please see JIRA DEV-14943 - Cmake Linux cannot build both VIEWER and SERVER in one build environment
|
|
||||||
")
|
|
||||||
endif (LINUX AND SERVER AND VIEWER)
|
|
||||||
|
|
||||||
source_group("CMake Rules" FILES CMakeLists.txt)
|
source_group("CMake Rules" FILES CMakeLists.txt)
|
||||||
|
|
||||||
|
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||||
|
|||||||
@@ -19,8 +19,3 @@ else (NOT STANDALONE)
|
|||||||
endif(LINUX AND ${ARCH} STREQUAL "x86_64")
|
endif(LINUX AND ${ARCH} STREQUAL "x86_64")
|
||||||
set(STANDALONE ON)
|
set(STANDALONE ON)
|
||||||
endif(NOT STANDALONE)
|
endif(NOT STANDALONE)
|
||||||
|
|
||||||
if (WINDOWS)
|
|
||||||
use_prebuilt_binary(dbghelp)
|
|
||||||
endif (WINDOWS)
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,10 @@
|
|||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
include(Linking)
|
include(Linking)
|
||||||
include(Prebuilt)
|
include(Prebuilt)
|
||||||
|
include(LLQtWebkit)
|
||||||
|
include(Qt4)
|
||||||
|
|
||||||
if (STANDALONE)
|
if (STANDALONE)
|
||||||
# The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny.
|
|
||||||
find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
|
|
||||||
include(${QT_USE_FILE})
|
|
||||||
set(QTDIR $ENV{QTDIR})
|
|
||||||
if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
|
|
||||||
message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; "
|
|
||||||
"Qt is found by looking for qmake in your PATH. "
|
|
||||||
"Please set your PATH such that 'qmake' is found in \$QTDIR/bin, "
|
|
||||||
"or unset QTDIR if the found Qt is correct.")
|
|
||||||
endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
|
|
||||||
find_package(LLQtWebkit REQUIRED QUIET)
|
|
||||||
# Add the plugins.
|
|
||||||
set(QT_PLUGIN_LIBRARIES)
|
|
||||||
foreach(qlibname qgif qjpeg)
|
|
||||||
find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH)
|
|
||||||
if (QT_PLUGIN_${qlibname})
|
|
||||||
list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}})
|
|
||||||
else (QT_PLUGIN_${qtlibname})
|
|
||||||
message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!")
|
|
||||||
endif (QT_PLUGIN_${qlibname})
|
|
||||||
endforeach(qlibname)
|
|
||||||
# qjpeg depends on libjpeg
|
|
||||||
list(APPEND QT_PLUGIN_LIBRARIES jpeg)
|
|
||||||
set(WEBKITLIBPLUGIN OFF CACHE BOOL
|
set(WEBKITLIBPLUGIN OFF CACHE BOOL
|
||||||
"WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
|
"WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
|
||||||
else (STANDALONE)
|
else (STANDALONE)
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
# -*- cmake -*-
|
|
||||||
|
|
||||||
project(cwdebug)
|
|
||||||
|
|
||||||
include(00-Common)
|
|
||||||
include(LLCommon)
|
|
||||||
include(LLMath)
|
|
||||||
include(LLMessage)
|
|
||||||
include(LLVFS)
|
|
||||||
|
|
||||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
set(cwdebug_SOURCE_FILES
|
|
||||||
debug.cc
|
|
||||||
)
|
|
||||||
|
|
||||||
set(cwdebug_HEADER_FILES
|
|
||||||
CMakeLists.txt
|
|
||||||
|
|
||||||
cwdebug.h
|
|
||||||
sys.h
|
|
||||||
debug.h
|
|
||||||
debug_ostream_operators.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set_source_files_properties(${cwdebug_HEADER_FILES}
|
|
||||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
|
||||||
|
|
||||||
if(NOT WORD_SIZE EQUAL 32)
|
|
||||||
if(WINDOWS)
|
|
||||||
add_definitions(/FIXED:NO)
|
|
||||||
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
|
|
||||||
add_definitions(-fPIC)
|
|
||||||
endif(WINDOWS)
|
|
||||||
endif (NOT WORD_SIZE EQUAL 32)
|
|
||||||
|
|
||||||
list(APPEND cwdebug_SOURCE_FILES ${cwdebug_HEADER_FILES})
|
|
||||||
|
|
||||||
add_library (cwdebug ${cwdebug_SOURCE_FILES})
|
|
||||||
@@ -49,6 +49,8 @@
|
|||||||
namespace debug {
|
namespace debug {
|
||||||
|
|
||||||
#if CWDEBUG_LOCATION
|
#if CWDEBUG_LOCATION
|
||||||
|
ll_thread_local size_t BackTrace::S_number;
|
||||||
|
|
||||||
void BackTrace::dump_backtrace(void) const
|
void BackTrace::dump_backtrace(void) const
|
||||||
{
|
{
|
||||||
for (int frame = 0; frame < frames(); ++frame)
|
for (int frame = 0; frame < frames(); ++frame)
|
||||||
@@ -67,6 +69,67 @@ void BackTrace::dump_backtrace(void) const
|
|||||||
Dout(dc::finish, mangled_function_name);
|
Dout(dc::finish, mangled_function_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BackTraces::store_trace(size_t trace)
|
||||||
|
{
|
||||||
|
mBackTraces.push_back(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackTraces::remove_trace(size_t trace)
|
||||||
|
{
|
||||||
|
trace_container_type::iterator iter = mBackTraces.begin();
|
||||||
|
while (iter != mBackTraces.end())
|
||||||
|
{
|
||||||
|
if (*iter == trace)
|
||||||
|
{
|
||||||
|
*iter = mBackTraces.back();
|
||||||
|
mBackTraces.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
DoutFatal(dc::core, "Trace doesn't exist!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackTraces::dump(void) const
|
||||||
|
{
|
||||||
|
Dout(dc::backtrace|continued_cf, "Dump for (BackTraces*)" << (void*)this << " (" << mBackTraces.size() << " backtraces): ");
|
||||||
|
for (trace_container_type::const_iterator iter = mBackTraces.begin(); iter != mBackTraces.end(); ++iter)
|
||||||
|
{
|
||||||
|
Dout(dc::continued|nonewline_cf, *iter << ' ');
|
||||||
|
}
|
||||||
|
Dout(dc::finish, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
BackTraceTracker::BackTraceTracker(BackTraces* back_traces) : mBackTraces(back_traces)
|
||||||
|
{
|
||||||
|
BACKTRACE;
|
||||||
|
mTrace = BackTrace::S_number;
|
||||||
|
mBackTraces->store_trace(mTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
BackTraceTracker::~BackTraceTracker()
|
||||||
|
{
|
||||||
|
mBackTraces->remove_trace(mTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
BackTraceTracker::BackTraceTracker(BackTraceTracker const& orig) : mBackTraces(orig.mBackTraces)
|
||||||
|
{
|
||||||
|
BACKTRACE;
|
||||||
|
mTrace = BackTrace::S_number;
|
||||||
|
mBackTraces->store_trace(mTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
BackTraceTracker& BackTraceTracker::operator=(BackTraceTracker const& orig)
|
||||||
|
{
|
||||||
|
mBackTraces->remove_trace(mTrace);
|
||||||
|
mBackTraces = orig.mBackTraces;
|
||||||
|
BACKTRACE;
|
||||||
|
mTrace = BackTrace::S_number;
|
||||||
|
mBackTraces->store_trace(mTrace);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // CWDEBUG_LOCATION
|
#endif // CWDEBUG_LOCATION
|
||||||
|
|
||||||
#if CWDEBUG_ALLOC && CWDEBUG_LOCATION
|
#if CWDEBUG_ALLOC && CWDEBUG_LOCATION
|
||||||
@@ -173,6 +236,10 @@ void stop_recording_backtraces(void)
|
|||||||
channel_ct backtrace DDCN("BACKTRACE"); //!< This debug channel is used for backtraces.
|
channel_ct backtrace DDCN("BACKTRACE"); //!< This debug channel is used for backtraces.
|
||||||
channel_ct statemachine DDCN("STATEMACHINE"); //!< This debug channel is used for output related to class AIStateMachine.
|
channel_ct statemachine DDCN("STATEMACHINE"); //!< This debug channel is used for output related to class AIStateMachine.
|
||||||
channel_ct caps DDCN("CAPS"); //!< This debug channel is used for output related to Capabilities.
|
channel_ct caps DDCN("CAPS"); //!< This debug channel is used for output related to Capabilities.
|
||||||
|
channel_ct curl DDCN("CURL"); //!< This debug channel is used for output related to AICurl.
|
||||||
|
channel_ct curlio DDCN("CURLIO"); //!< This debug channel is used to print debug output of libcurl. This includes all HTTP network traffic.
|
||||||
|
channel_ct curltr DDCN("CURLTR"); //!< This debug channel is used to print libcurl API calls.
|
||||||
|
channel_ct snapshot DDCN("SNAPSHOT"); //!< This debug channel is used for output related to snapshots.
|
||||||
|
|
||||||
} // namespace dc
|
} // namespace dc
|
||||||
} // namespace DEBUGCHANNELS
|
} // namespace DEBUGCHANNELS
|
||||||
@@ -411,4 +478,96 @@ void cwdebug_backtrace(int n)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // CWDEBUG
|
#elif defined(DEBUG_CURLIO)
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "aithreadid.h"
|
||||||
|
|
||||||
|
namespace debug
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace libcwd { libcwd_do_type const libcw_do; }
|
||||||
|
|
||||||
|
ll_thread_local int Indent::S_indentation;
|
||||||
|
|
||||||
|
Indent::Indent(int indent) : M_indent(indent)
|
||||||
|
{
|
||||||
|
S_indentation += M_indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Indent::~Indent()
|
||||||
|
{
|
||||||
|
S_indentation -= M_indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, Indent::print_nt)
|
||||||
|
{
|
||||||
|
if (Indent::S_indentation)
|
||||||
|
os << std::string(Indent::S_indentation, ' ');
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CURLIO
|
||||||
|
std::ostream& operator<<(std::ostream& os, print_thread_id_t)
|
||||||
|
{
|
||||||
|
if (!AIThreadID::in_main_thread_inline())
|
||||||
|
{
|
||||||
|
os << std::hex << (size_t)AIThreadID::getCurrentThread_inline() << std::dec << ' ';
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s)
|
||||||
|
{
|
||||||
|
static char const c2s_tab[7] = { 'a', 'b', 't', 'n', 'v', 'f', 'r' };
|
||||||
|
size_t size = b2s.mSize;
|
||||||
|
for (char const* p1 = b2s.mBuf; size > 0; --size, ++p1)
|
||||||
|
{
|
||||||
|
char c =*p1;
|
||||||
|
if ((c > 31 && c != 92 && c != 127) || (unsigned char)c > 159)
|
||||||
|
os.put(c);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os.put('\\');
|
||||||
|
if (c > 6 && c < 14)
|
||||||
|
{
|
||||||
|
os.put(c2s_tab[c - 7]);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
else if (c == 27)
|
||||||
|
{
|
||||||
|
os.put('e');
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
else if (c == '\\')
|
||||||
|
{
|
||||||
|
os.put('\\');
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
std::ostream::char_type old_fill = os.fill('0');
|
||||||
|
std::ios_base::fmtflags old_flgs = os.flags();
|
||||||
|
os.width(3);
|
||||||
|
os << std::oct << (int)((unsigned char)c);
|
||||||
|
os.setf(old_flgs);
|
||||||
|
os.fill(old_fill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace dc
|
||||||
|
{
|
||||||
|
|
||||||
|
fake_channel const warning(1, "WARNING ");
|
||||||
|
fake_channel const curl(1, "CURL ");
|
||||||
|
fake_channel const curlio(1, "CURLIO ");
|
||||||
|
fake_channel const curltr(1, "CURLTR ");
|
||||||
|
fake_channel const statemachine(1, "STATEMACHINE");
|
||||||
|
fake_channel const notice(1, "NOTICE ");
|
||||||
|
fake_channel const snapshot(0, "SNAPSHOT ");
|
||||||
|
|
||||||
|
} // namespace dc
|
||||||
|
} // namespace debug
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -27,6 +27,96 @@
|
|||||||
|
|
||||||
#ifndef CWDEBUG
|
#ifndef CWDEBUG
|
||||||
|
|
||||||
|
#ifdef DEBUG_CURLIO
|
||||||
|
|
||||||
|
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
|
||||||
|
// some of the cwd macro's with something that generates viewer
|
||||||
|
// specific debug output. Note that this generates a LOT of
|
||||||
|
// output and should not normally be defined.
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "llpreprocessor.h"
|
||||||
|
|
||||||
|
namespace debug {
|
||||||
|
namespace libcwd {
|
||||||
|
|
||||||
|
struct buf2str {
|
||||||
|
buf2str(char const* buf, int size) : mBuf(buf), mSize(size) { }
|
||||||
|
char const* mBuf;
|
||||||
|
int mSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct libcwd_do_type {
|
||||||
|
void on() const { }
|
||||||
|
};
|
||||||
|
extern LL_COMMON_API libcwd_do_type const libcw_do;
|
||||||
|
|
||||||
|
} // namespace libcwd
|
||||||
|
|
||||||
|
enum print_thread_id_t { print_thread_id };
|
||||||
|
inline void init() { }
|
||||||
|
struct Indent {
|
||||||
|
int M_indent;
|
||||||
|
static ll_thread_local int S_indentation;
|
||||||
|
enum LL_COMMON_API print_nt { print };
|
||||||
|
LL_COMMON_API Indent(int indent);
|
||||||
|
LL_COMMON_API ~Indent();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s);
|
||||||
|
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, Indent::print_nt);
|
||||||
|
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, print_thread_id_t);
|
||||||
|
|
||||||
|
namespace dc {
|
||||||
|
|
||||||
|
struct fake_channel {
|
||||||
|
int mOn;
|
||||||
|
char const* mLabel;
|
||||||
|
fake_channel(int on, char const* label) : mOn(on), mLabel(label) { }
|
||||||
|
fake_channel(void) : mOn(0) { }
|
||||||
|
bool is_on() const { return !!mOn; }
|
||||||
|
bool is_off() const { return !mOn; }
|
||||||
|
void on() const { }
|
||||||
|
void off() const { }
|
||||||
|
};
|
||||||
|
extern LL_COMMON_API fake_channel const warning;
|
||||||
|
extern LL_COMMON_API fake_channel const curl;
|
||||||
|
extern LL_COMMON_API fake_channel const curlio;
|
||||||
|
extern LL_COMMON_API fake_channel const curltr;
|
||||||
|
extern LL_COMMON_API fake_channel const statemachine;
|
||||||
|
extern LL_COMMON_API fake_channel const notice;
|
||||||
|
extern LL_COMMON_API fake_channel const snapshot;
|
||||||
|
|
||||||
|
} // namespace dc
|
||||||
|
} // namespace debug
|
||||||
|
|
||||||
|
#define LIBCWD_DEBUG_CHANNELS debug
|
||||||
|
#define LibcwDoutScopeBegin(a, b, c) do { using namespace debug; using namespace debug::libcwd; llinfos_nf << print_thread_id << (c).mLabel << ": " << Indent::print;
|
||||||
|
#define LibcwDoutStream llcont
|
||||||
|
#define LibcwDoutScopeEnd llcont << llendl; } while(0)
|
||||||
|
|
||||||
|
#define Debug(x) do { using namespace debug; using namespace debug::libcwd; x; } while(0)
|
||||||
|
#define Dout(a, b) do { using namespace debug; using namespace debug::libcwd; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
|
||||||
|
#define DoutEntering(a, b) \
|
||||||
|
int __slviewer_debug_indentation = 2; \
|
||||||
|
{ \
|
||||||
|
using namespace debug; \
|
||||||
|
using namespace debug::libcwd; \
|
||||||
|
if ((a).mOn) \
|
||||||
|
llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
|
||||||
|
else \
|
||||||
|
__slviewer_debug_indentation = 0; \
|
||||||
|
} \
|
||||||
|
debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
|
||||||
|
|
||||||
|
#else // !DEBUG_CURLIO
|
||||||
|
|
||||||
|
#define Debug(x)
|
||||||
|
#define Dout(a, b)
|
||||||
|
#define DoutEntering(a, b)
|
||||||
|
|
||||||
|
#endif // !DEBUG_CURLIO
|
||||||
|
|
||||||
#ifndef DOXYGEN // No need to document this. See http://libcwd.sourceforge.net/ for more info.
|
#ifndef DOXYGEN // No need to document this. See http://libcwd.sourceforge.net/ for more info.
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -36,9 +126,6 @@
|
|||||||
#define AllocTag2(p, desc)
|
#define AllocTag2(p, desc)
|
||||||
#define AllocTag_dynamic_description(p, x)
|
#define AllocTag_dynamic_description(p, x)
|
||||||
#define AllocTag(p, x)
|
#define AllocTag(p, x)
|
||||||
#define Debug(x)
|
|
||||||
#define Dout(a, b)
|
|
||||||
#define DoutEntering(a, b)
|
|
||||||
#define DoutFatal(a, b) LibcwDoutFatal(::std, , a, b)
|
#define DoutFatal(a, b) LibcwDoutFatal(::std, , a, b)
|
||||||
#define ForAllDebugChannels(STATEMENT)
|
#define ForAllDebugChannels(STATEMENT)
|
||||||
#define ForAllDebugObjects(STATEMENT)
|
#define ForAllDebugObjects(STATEMENT)
|
||||||
@@ -89,6 +176,8 @@
|
|||||||
#if CWDEBUG_LOCATION
|
#if CWDEBUG_LOCATION
|
||||||
#include <execinfo.h> // Needed for 'backtrace'.
|
#include <execinfo.h> // Needed for 'backtrace'.
|
||||||
#endif
|
#endif
|
||||||
|
#include "llpreprocessor.h" // LL_COMMON_API
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#define CWD_API __attribute__ ((visibility("default")))
|
#define CWD_API __attribute__ ((visibility("default")))
|
||||||
|
|
||||||
@@ -118,6 +207,10 @@ extern CWD_API channel_ct sdl;
|
|||||||
extern CWD_API channel_ct backtrace;
|
extern CWD_API channel_ct backtrace;
|
||||||
extern CWD_API channel_ct statemachine;
|
extern CWD_API channel_ct statemachine;
|
||||||
extern CWD_API channel_ct caps;
|
extern CWD_API channel_ct caps;
|
||||||
|
extern CWD_API channel_ct curl;
|
||||||
|
extern CWD_API channel_ct curlio;
|
||||||
|
extern CWD_API channel_ct curltr;
|
||||||
|
extern CWD_API channel_ct snapshot;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -186,6 +279,8 @@ class BackTrace {
|
|||||||
private:
|
private:
|
||||||
boost::shared_array<void*> M_buffer;
|
boost::shared_array<void*> M_buffer;
|
||||||
int M_frames;
|
int M_frames;
|
||||||
|
public:
|
||||||
|
static ll_thread_local size_t S_number;
|
||||||
public:
|
public:
|
||||||
BackTrace(void** buffer, int frames) : M_buffer(new void* [frames]), M_frames(frames) { std::memcpy(M_buffer.get(), buffer, sizeof(void*) * frames); }
|
BackTrace(void** buffer, int frames) : M_buffer(new void* [frames]), M_frames(frames) { std::memcpy(M_buffer.get(), buffer, sizeof(void*) * frames); }
|
||||||
|
|
||||||
@@ -212,19 +307,81 @@ extern pthread_mutex_t backtrace_mutex;
|
|||||||
using namespace debug; \
|
using namespace debug; \
|
||||||
void* buffer[32]; \
|
void* buffer[32]; \
|
||||||
int frames = backtrace(buffer, 32); \
|
int frames = backtrace(buffer, 32); \
|
||||||
size_t size; \
|
|
||||||
{ \
|
{ \
|
||||||
pthread_mutex_lock(&backtrace_mutex); \
|
pthread_mutex_lock(&backtrace_mutex); \
|
||||||
backtraces.push_back(BackTrace(buffer, frames)); \
|
backtraces.push_back(BackTrace(buffer, frames)); \
|
||||||
size = backtraces.size(); \
|
BackTrace::S_number = backtraces.size(); \
|
||||||
pthread_mutex_unlock(&backtrace_mutex); \
|
pthread_mutex_unlock(&backtrace_mutex); \
|
||||||
} \
|
} \
|
||||||
Dout(dc::backtrace, "Stored backtrace #" << size); \
|
Dout(dc::backtrace, "Stored backtrace #" << BackTrace::S_number); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
class LL_COMMON_API BackTraces {
|
||||||
|
private:
|
||||||
|
typedef std::vector<size_t> trace_container_type;
|
||||||
|
trace_container_type mBackTraces;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void store_trace(size_t trace);
|
||||||
|
void remove_trace(size_t trace);
|
||||||
|
|
||||||
|
void dump(void) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LL_COMMON_API BackTraceTracker {
|
||||||
|
private:
|
||||||
|
BackTraces* mBackTraces;
|
||||||
|
size_t mTrace;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BackTraceTracker(BackTraces* back_traces);
|
||||||
|
~BackTraceTracker();
|
||||||
|
|
||||||
|
BackTraceTracker(BackTraceTracker const&);
|
||||||
|
BackTraceTracker& operator=(BackTraceTracker const&);
|
||||||
|
|
||||||
|
void dump(void) const { mBackTraces->dump(); }
|
||||||
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define BACKTRACE do { } while(0)
|
#define BACKTRACE do { } while(0)
|
||||||
#endif // CWDEBUG_LOCATION
|
#endif // CWDEBUG_LOCATION
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class LL_COMMON_API InstanceTracker {
|
||||||
|
private:
|
||||||
|
T const* mInstance;
|
||||||
|
static pthread_mutex_t sInstancesMutex;
|
||||||
|
static std::set<T const*> sInstances;
|
||||||
|
static void remember(T const* instance) { pthread_mutex_lock(&sInstancesMutex); sInstances.insert(instance); pthread_mutex_unlock(&sInstancesMutex); }
|
||||||
|
static void forget(T const* instance) { pthread_mutex_lock(&sInstancesMutex); sInstances.erase(instance); pthread_mutex_unlock(&sInstancesMutex); }
|
||||||
|
public:
|
||||||
|
InstanceTracker(T const* instance) : mInstance(instance) { remember(mInstance); }
|
||||||
|
~InstanceTracker() { forget(mInstance); }
|
||||||
|
InstanceTracker& operator=(InstanceTracker const& orig) { forget(mInstance); mInstance = orig.mInstance; remember(mInstance); return *this; }
|
||||||
|
static void dump(void);
|
||||||
|
private:
|
||||||
|
// Non-copyable. Instead of copying, call InstanceTracker(T const*) with the this pointer of the new instance.
|
||||||
|
InstanceTracker(InstanceTracker const& orig);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
pthread_mutex_t InstanceTracker<T>::sInstancesMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
std::set<T const*> InstanceTracker<T>::sInstances;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void InstanceTracker<T>::dump(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&sInstancesMutex);
|
||||||
|
for (typename std::set<T const*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
|
||||||
|
{
|
||||||
|
std::cout << *iter << std::endl;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&sInstancesMutex);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace debug
|
} // namespace debug
|
||||||
|
|
||||||
//! Debugging macro.
|
//! Debugging macro.
|
||||||
@@ -232,21 +389,21 @@ extern pthread_mutex_t backtrace_mutex;
|
|||||||
// Print "Entering " << \a data to channel \a cntrl and increment
|
// Print "Entering " << \a data to channel \a cntrl and increment
|
||||||
// debugging output indentation until the end of the current scope.
|
// debugging output indentation until the end of the current scope.
|
||||||
#define DoutEntering(cntrl, data) \
|
#define DoutEntering(cntrl, data) \
|
||||||
int __slviewer_debug_indentation = 2; \
|
int __slviewer_debug_indentation = 2; \
|
||||||
{ \
|
{ \
|
||||||
LIBCWD_TSD_DECLARATION; \
|
LIBCWD_TSD_DECLARATION; \
|
||||||
if (LIBCWD_DO_TSD_MEMBER_OFF(::libcwd::libcw_do) < 0) \
|
if (LIBCWD_DO_TSD_MEMBER_OFF(::libcwd::libcw_do) < 0) \
|
||||||
{ \
|
{ \
|
||||||
::libcwd::channel_set_bootstrap_st __libcwd_channel_set(LIBCWD_DO_TSD(::libcwd::libcw_do) LIBCWD_COMMA_TSD); \
|
::libcwd::channel_set_bootstrap_st __libcwd_channel_set(LIBCWD_DO_TSD(::libcwd::libcw_do) LIBCWD_COMMA_TSD); \
|
||||||
bool on; \
|
bool __slviewer_debug_on; \
|
||||||
{ \
|
{ \
|
||||||
using namespace LIBCWD_DEBUGCHANNELS; \
|
using namespace LIBCWD_DEBUGCHANNELS; \
|
||||||
on = (__libcwd_channel_set|cntrl).on; \
|
__slviewer_debug_on = (__libcwd_channel_set|cntrl).on; \
|
||||||
} \
|
} \
|
||||||
if (on) \
|
if (__slviewer_debug_on) \
|
||||||
Dout(cntrl, "Entering " << data); \
|
Dout(cntrl, "Entering " << data); \
|
||||||
else \
|
else \
|
||||||
__slviewer_debug_indentation = 0; \
|
__slviewer_debug_indentation = 0; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
|
debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ class PlatformSetup(object):
|
|||||||
distcc = True
|
distcc = True
|
||||||
cmake_opts = []
|
cmake_opts = []
|
||||||
word_size = 32
|
word_size = 32
|
||||||
opensim_rules = 'OFF' #whether or not to use rules fit for opensim
|
|
||||||
using_express = False
|
using_express = False
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -125,7 +124,6 @@ class PlatformSetup(object):
|
|||||||
standalone=self.standalone,
|
standalone=self.standalone,
|
||||||
unattended=self.unattended,
|
unattended=self.unattended,
|
||||||
word_size=self.word_size,
|
word_size=self.word_size,
|
||||||
opensim_rules=self.opensim_rules,
|
|
||||||
type=self.build_type.upper(),
|
type=self.build_type.upper(),
|
||||||
)
|
)
|
||||||
#if simple:
|
#if simple:
|
||||||
@@ -134,7 +132,6 @@ class PlatformSetup(object):
|
|||||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||||
'-DOPENSIM_RULES:BOOL=%(opensim_rules)s '
|
|
||||||
'-G %(generator)r %(opts)s %(dir)r' % args)
|
'-G %(generator)r %(opts)s %(dir)r' % args)
|
||||||
|
|
||||||
def run_cmake(self, args=[]):
|
def run_cmake(self, args=[]):
|
||||||
@@ -296,7 +293,6 @@ class LinuxSetup(UnixSetup):
|
|||||||
type=self.build_type.upper(),
|
type=self.build_type.upper(),
|
||||||
project_name=self.project_name,
|
project_name=self.project_name,
|
||||||
word_size=self.word_size,
|
word_size=self.word_size,
|
||||||
opensim_rules=self.opensim_rules,
|
|
||||||
)
|
)
|
||||||
if not self.is_internal_tree():
|
if not self.is_internal_tree():
|
||||||
args.update({'cxx':'g++', 'server':'OFF', 'viewer':'ON'})
|
args.update({'cxx':'g++', 'server':'OFF', 'viewer':'ON'})
|
||||||
@@ -323,7 +319,6 @@ class LinuxSetup(UnixSetup):
|
|||||||
'-DVIEWER:BOOL=%(viewer)s -DSTANDALONE:BOOL=%(standalone)s '
|
'-DVIEWER:BOOL=%(viewer)s -DSTANDALONE:BOOL=%(standalone)s '
|
||||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||||
'-DOPENSIM_RULES:BOOL=%(opensim_rules)s '
|
|
||||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||||
'%(opts)s %(dir)r')
|
'%(opts)s %(dir)r')
|
||||||
% args)
|
% args)
|
||||||
@@ -437,7 +432,6 @@ class DarwinSetup(UnixSetup):
|
|||||||
unattended=self.unattended,
|
unattended=self.unattended,
|
||||||
project_name=self.project_name,
|
project_name=self.project_name,
|
||||||
universal=self.universal,
|
universal=self.universal,
|
||||||
opensim_rules=self.opensim_rules,
|
|
||||||
type=self.build_type.upper(),
|
type=self.build_type.upper(),
|
||||||
)
|
)
|
||||||
if self.universal == 'ON':
|
if self.universal == 'ON':
|
||||||
@@ -449,7 +443,6 @@ class DarwinSetup(UnixSetup):
|
|||||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||||
'-DOPENSIM_RULES:BOOL=%(opensim_rules)s '
|
|
||||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||||
'%(universal)s '
|
'%(universal)s '
|
||||||
'%(opts)s %(dir)r' % args)
|
'%(opts)s %(dir)r' % args)
|
||||||
@@ -473,26 +466,11 @@ class DarwinSetup(UnixSetup):
|
|||||||
|
|
||||||
class WindowsSetup(PlatformSetup):
|
class WindowsSetup(PlatformSetup):
|
||||||
gens = {
|
gens = {
|
||||||
'vc71' : {
|
|
||||||
'gen' : r'Visual Studio 7 .NET 2003',
|
|
||||||
'ver' : r'7.1'
|
|
||||||
},
|
|
||||||
'vc80' : {
|
|
||||||
'gen' : r'Visual Studio 8 2005',
|
|
||||||
'ver' : r'8.0'
|
|
||||||
},
|
|
||||||
'vc90' : {
|
|
||||||
'gen' : r'Visual Studio 9 2008',
|
|
||||||
'ver' : r'9.0'
|
|
||||||
},
|
|
||||||
'vc100' : {
|
'vc100' : {
|
||||||
'gen' : r'Visual Studio 10',
|
'gen' : r'Visual Studio 10',
|
||||||
'ver' : r'10.0'
|
'ver' : r'10.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gens['vs2003'] = gens['vc71']
|
|
||||||
gens['vs2005'] = gens['vc80']
|
|
||||||
gens['vs2008'] = gens['vc90']
|
|
||||||
gens['vs2010'] = gens['vc100']
|
gens['vs2010'] = gens['vc100']
|
||||||
|
|
||||||
search_path = r'C:\windows'
|
search_path = r'C:\windows'
|
||||||
@@ -505,21 +483,21 @@ class WindowsSetup(PlatformSetup):
|
|||||||
|
|
||||||
def _get_generator(self):
|
def _get_generator(self):
|
||||||
if self._generator is None:
|
if self._generator is None:
|
||||||
for version in 'vc80 vc90 vc100 vc71'.split():
|
for version in 'vc100'.split():
|
||||||
if self.find_visual_studio(version):
|
if self.find_visual_studio(version):
|
||||||
self._generator = version
|
self._generator = version
|
||||||
print 'Building with ', self.gens[version]['gen']
|
print 'Building with ', self.gens[version]['gen']
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print >> sys.stderr, 'Cannot find a Visual Studio installation, testing for express editions'
|
print >> sys.stderr, 'Cannot find a Visual Studio installation, testing for express editions'
|
||||||
for version in 'vc80 vc90 vc100 vc71'.split():
|
for version in 'vc100'.split():
|
||||||
if self.find_visual_studio_express(version):
|
if self.find_visual_studio_express(version):
|
||||||
self._generator = version
|
self._generator = version
|
||||||
self.using_express = True
|
self.using_express = True
|
||||||
print 'Building with ', self.gens[version]['gen'] , "Express edition"
|
print 'Building with ', self.gens[version]['gen'] , "Express edition"
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
for version in 'vc80 vc90 vc100 vc71'.split():
|
for version in 'vc100'.split():
|
||||||
if self.find_visual_studio_express_single(version):
|
if self.find_visual_studio_express_single(version):
|
||||||
self._generator = version
|
self._generator = version
|
||||||
self.using_express = True
|
self.using_express = True
|
||||||
@@ -550,7 +528,6 @@ class WindowsSetup(PlatformSetup):
|
|||||||
unattended=self.unattended,
|
unattended=self.unattended,
|
||||||
project_name=self.project_name,
|
project_name=self.project_name,
|
||||||
word_size=self.word_size,
|
word_size=self.word_size,
|
||||||
opensim_rules=self.opensim_rules,
|
|
||||||
)
|
)
|
||||||
#if simple:
|
#if simple:
|
||||||
# return 'cmake %(opts)s "%(dir)s"' % args
|
# return 'cmake %(opts)s "%(dir)s"' % args
|
||||||
@@ -558,7 +535,6 @@ class WindowsSetup(PlatformSetup):
|
|||||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||||
'-DUNATTENDED:BOOL=%(unattended)s '
|
'-DUNATTENDED:BOOL=%(unattended)s '
|
||||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||||
'-DOPENSIM_RULES:BOOL=%(opensim_rules)s '
|
|
||||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||||
'%(opts)s "%(dir)s"' % args)
|
'%(opts)s "%(dir)s"' % args)
|
||||||
|
|
||||||
@@ -734,7 +710,6 @@ class CygwinSetup(WindowsSetup):
|
|||||||
unattended=self.unattended,
|
unattended=self.unattended,
|
||||||
project_name=self.project_name,
|
project_name=self.project_name,
|
||||||
word_size=self.word_size,
|
word_size=self.word_size,
|
||||||
opensim_rules=self.opensim_rules,
|
|
||||||
)
|
)
|
||||||
#if simple:
|
#if simple:
|
||||||
# return 'cmake %(opts)s "%(dir)s"' % args
|
# return 'cmake %(opts)s "%(dir)s"' % args
|
||||||
@@ -742,7 +717,6 @@ class CygwinSetup(WindowsSetup):
|
|||||||
'-DUNATTENDED:BOOl=%(unattended)s '
|
'-DUNATTENDED:BOOl=%(unattended)s '
|
||||||
'-DSTANDALONE:BOOL=%(standalone)s '
|
'-DSTANDALONE:BOOL=%(standalone)s '
|
||||||
'-DWORD_SIZE:STRING=%(word_size)s '
|
'-DWORD_SIZE:STRING=%(word_size)s '
|
||||||
'-DOPENSIM_RULES:BOOL=%(opensim_rules)s '
|
|
||||||
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
|
||||||
'%(opts)s "%(dir)s"' % args)
|
'%(opts)s "%(dir)s"' % args)
|
||||||
|
|
||||||
@@ -768,8 +742,7 @@ Options:
|
|||||||
-m32 | -m64 build architecture (32-bit or 64-bit)
|
-m32 | -m64 build architecture (32-bit or 64-bit)
|
||||||
-N | --no-distcc disable use of distcc
|
-N | --no-distcc disable use of distcc
|
||||||
-G | --generator=NAME generator name
|
-G | --generator=NAME generator name
|
||||||
Windows: VC71 or VS2003 (default), VC80 (VS2005)
|
Windows: VC100 (VS2010) (default)
|
||||||
VC90 (VS2008), or VC100 (VS2010)
|
|
||||||
Mac OS X: Xcode (default), Unix Makefiles
|
Mac OS X: Xcode (default), Unix Makefiles
|
||||||
Linux: Unix Makefiles (default), KDevelop3
|
Linux: Unix Makefiles (default), KDevelop3
|
||||||
-p | --project=NAME set the root project name. (Doesn't effect makefiles)
|
-p | --project=NAME set the root project name. (Doesn't effect makefiles)
|
||||||
@@ -782,20 +755,15 @@ Commands:
|
|||||||
|
|
||||||
Command-options for "configure":
|
Command-options for "configure":
|
||||||
We use cmake variables to change the build configuration.
|
We use cmake variables to change the build configuration.
|
||||||
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
|
-DPACKAGE:BOOL=ON Create "package" target to make installers
|
||||||
-DVIEWER:BOOL=OFF Don't configure the viewer
|
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
|
||||||
-DPACKAGE:BOOL=ON Create "package" target to make installers
|
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
|
||||||
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
|
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
|
||||||
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
|
-DDISABLE_TCMALLOC:BOOL=ON Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)
|
||||||
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
|
|
||||||
-VISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!)
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
Set up a viewer-only project for your system:
|
Set up a Visual Studio 2010 project with "package" target:
|
||||||
develop.py configure -DSERVER:BOOL=OFF
|
develop.py -G vc100 configure -DPACKAGE:BOOL=ON
|
||||||
|
|
||||||
Set up a Visual Studio 2005 project with "package" target:
|
|
||||||
develop.py -G vc80 configure -DPACKAGE:BOOL=ON
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def main(arguments):
|
def main(arguments):
|
||||||
|
|||||||
13
indra/libhacd/CMakeLists.txt
Normal file
13
indra/libhacd/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.6.4)
|
||||||
|
|
||||||
|
project(libhacd CXX C)
|
||||||
|
include(00-Common)
|
||||||
|
|
||||||
|
file (GLOB SOURCE_FILES *.cpp )
|
||||||
|
file (GLOB INCLUDE_FILES *.h )
|
||||||
|
|
||||||
|
IF(WINDOWS)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
ENDIF(WINDOWS)
|
||||||
|
|
||||||
|
add_library(hacd ${SOURCE_FILES} ${INCLUDE_FILES})
|
||||||
85
indra/libhacd/hacdCircularList.h
Normal file
85
indra/libhacd/hacdCircularList.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_CIRCULAR_LIST_H
|
||||||
|
#define HACD_CIRCULAR_LIST_H
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include "hacdMicroAllocator.h"
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
//! CircularListElement class.
|
||||||
|
template < typename T > class CircularListElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T & GetData() { return m_data; }
|
||||||
|
const T & GetData() const { return m_data; }
|
||||||
|
CircularListElement<T> * & GetNext() { return m_next; }
|
||||||
|
CircularListElement<T> * & GetPrev() { return m_prev; }
|
||||||
|
const CircularListElement<T> * & GetNext() const { return m_next; }
|
||||||
|
const CircularListElement<T> * & GetPrev() const { return m_prev; }
|
||||||
|
//! Constructor
|
||||||
|
CircularListElement(const T & data) {m_data = data;}
|
||||||
|
CircularListElement(void){}
|
||||||
|
//! Destructor
|
||||||
|
~CircularListElement(void){}
|
||||||
|
private:
|
||||||
|
T m_data;
|
||||||
|
CircularListElement<T> * m_next;
|
||||||
|
CircularListElement<T> * m_prev;
|
||||||
|
|
||||||
|
CircularListElement(const CircularListElement & rhs);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! CircularList class.
|
||||||
|
template < typename T > class CircularList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeapManager * const GetHeapManager() const { return m_heapManager;}
|
||||||
|
void SetHeapManager(HeapManager * const heapManager) { m_heapManager = heapManager;}
|
||||||
|
CircularListElement<T> * & GetHead() { return m_head;}
|
||||||
|
const CircularListElement<T> * GetHead() const { return m_head;}
|
||||||
|
bool IsEmpty() const { return (m_size == 0);}
|
||||||
|
size_t GetSize() const { return m_size; }
|
||||||
|
const T & GetData() const { return m_head->GetData(); }
|
||||||
|
T & GetData() { return m_head->GetData();}
|
||||||
|
bool Delete() ;
|
||||||
|
bool Delete(CircularListElement<T> * element);
|
||||||
|
CircularListElement<T> * Add(const T * data = 0);
|
||||||
|
CircularListElement<T> * Add(const T & data);
|
||||||
|
bool Next();
|
||||||
|
bool Prev();
|
||||||
|
void Clear() { while(Delete());};
|
||||||
|
const CircularList& operator=(const CircularList& rhs);
|
||||||
|
//! Constructor
|
||||||
|
CircularList(HeapManager * heapManager)
|
||||||
|
{
|
||||||
|
m_head = 0;
|
||||||
|
m_size = 0;
|
||||||
|
m_heapManager = heapManager;
|
||||||
|
}
|
||||||
|
CircularList(const CircularList& rhs);
|
||||||
|
//! Destructor
|
||||||
|
virtual ~CircularList(void) {Clear();};
|
||||||
|
private:
|
||||||
|
CircularListElement<T> * m_head; //!< a pointer to the head of the circular list
|
||||||
|
size_t m_size; //!< number of element in the circular list
|
||||||
|
HeapManager * m_heapManager;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#include "hacdCircularList.inl"
|
||||||
|
#endif
|
||||||
230
indra/libhacd/hacdCircularList.inl
Normal file
230
indra/libhacd/hacdCircularList.inl
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef HACD_CIRCULAR_LIST_INL
|
||||||
|
#define HACD_CIRCULAR_LIST_INL
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
template < typename T >
|
||||||
|
inline bool CircularList<T>::Delete(CircularListElement<T> * element)
|
||||||
|
{
|
||||||
|
if (!element)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_size > 1)
|
||||||
|
{
|
||||||
|
CircularListElement<T> * next = element->GetNext();
|
||||||
|
CircularListElement<T> * prev = element->GetPrev();
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
element->~CircularListElement<T>();
|
||||||
|
heap_free(m_heapManager, element);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete element;
|
||||||
|
}
|
||||||
|
m_size--;
|
||||||
|
if (element == m_head)
|
||||||
|
{
|
||||||
|
m_head = next;
|
||||||
|
}
|
||||||
|
next->GetPrev() = prev;
|
||||||
|
prev->GetNext() = next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (m_size == 1)
|
||||||
|
{
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
element->~CircularListElement<T>();
|
||||||
|
heap_free(m_heapManager, m_head);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete m_head;
|
||||||
|
}
|
||||||
|
m_size--;
|
||||||
|
m_head = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
inline bool CircularList<T>::Delete()
|
||||||
|
{
|
||||||
|
if (m_size > 1)
|
||||||
|
{
|
||||||
|
CircularListElement<T> * next = m_head->GetNext();
|
||||||
|
CircularListElement<T> * prev = m_head->GetPrev();
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
m_head->~CircularListElement<T>();
|
||||||
|
heap_free(m_heapManager, m_head);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete m_head;
|
||||||
|
}
|
||||||
|
m_size--;
|
||||||
|
m_head = next;
|
||||||
|
next->GetPrev() = prev;
|
||||||
|
prev->GetNext() = next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (m_size == 1)
|
||||||
|
{
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
m_head->~CircularListElement<T>();
|
||||||
|
heap_free(m_heapManager, m_head);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete m_head;
|
||||||
|
}
|
||||||
|
m_size--;
|
||||||
|
m_head = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template < typename T >
|
||||||
|
inline CircularListElement<T> * CircularList<T>::Add(const T * data)
|
||||||
|
{
|
||||||
|
if (m_size == 0)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
|
||||||
|
m_head->GetData().Initialize();
|
||||||
|
m_head->GetData() = (*data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_head = new CircularListElement<T>(*data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
|
||||||
|
m_head->GetData().Initialize();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_head = new CircularListElement<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_head->GetNext() = m_head->GetPrev() = m_head;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CircularListElement<T> * next = m_head->GetNext();
|
||||||
|
CircularListElement<T> * element = m_head;
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
|
||||||
|
m_head->GetData().Initialize();
|
||||||
|
m_head->GetData() = (*data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_head = new CircularListElement<T>(*data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_heapManager)
|
||||||
|
{
|
||||||
|
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
|
||||||
|
m_head->GetData().Initialize();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_head = new CircularListElement<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_head->GetNext() = next;
|
||||||
|
m_head->GetPrev() = element;
|
||||||
|
element->GetNext() = m_head;
|
||||||
|
next->GetPrev() = m_head;
|
||||||
|
}
|
||||||
|
m_size++;
|
||||||
|
return m_head;
|
||||||
|
}
|
||||||
|
template < typename T >
|
||||||
|
inline CircularListElement<T> * CircularList<T>::Add(const T & data)
|
||||||
|
{
|
||||||
|
const T * pData = &data;
|
||||||
|
return Add(pData);
|
||||||
|
}
|
||||||
|
template < typename T >
|
||||||
|
inline bool CircularList<T>::Next()
|
||||||
|
{
|
||||||
|
if (m_size == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_head = m_head->GetNext();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template < typename T >
|
||||||
|
inline bool CircularList<T>::Prev()
|
||||||
|
{
|
||||||
|
if (m_size == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_head = m_head->GetPrev();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template < typename T >
|
||||||
|
inline CircularList<T>::CircularList(const CircularList& rhs)
|
||||||
|
{
|
||||||
|
if (rhs.m_size > 0)
|
||||||
|
{
|
||||||
|
CircularListElement<T> * current = rhs.m_head;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
current = current->GetNext();
|
||||||
|
Add(current->GetData());
|
||||||
|
}
|
||||||
|
while ( current != rhs.m_head );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template < typename T >
|
||||||
|
inline const CircularList<T>& CircularList<T>::operator=(const CircularList& rhs)
|
||||||
|
{
|
||||||
|
if (&rhs != this)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
m_heapManager = rhs.m_heapManager;
|
||||||
|
if (rhs.m_size > 0)
|
||||||
|
{
|
||||||
|
CircularListElement<T> * current = rhs.m_head;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
current = current->GetNext();
|
||||||
|
Add(current->GetData());
|
||||||
|
}
|
||||||
|
while ( current != rhs.m_head );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
278
indra/libhacd/hacdGraph.cpp
Normal file
278
indra/libhacd/hacdGraph.cpp
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#include "hacdGraph.h"
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
|
||||||
|
GraphEdge::GraphEdge()
|
||||||
|
{
|
||||||
|
m_v1 = -1;
|
||||||
|
m_v2 = -1;
|
||||||
|
m_name = -1;
|
||||||
|
m_error = 0;
|
||||||
|
m_concavity = 0;
|
||||||
|
m_deleted = false;
|
||||||
|
#ifdef HACD_PRECOMPUTE_CHULLS
|
||||||
|
m_convexHull = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphVertex::GraphVertex()
|
||||||
|
{
|
||||||
|
m_convexHull = 0;
|
||||||
|
m_name = -1;
|
||||||
|
m_cc = -1;
|
||||||
|
m_concavity = 0;
|
||||||
|
m_surf = 0;
|
||||||
|
m_deleted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GraphVertex::DeleteEdge(long name)
|
||||||
|
{
|
||||||
|
return m_edges.Erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph::Graph()
|
||||||
|
{
|
||||||
|
m_nV = 0;
|
||||||
|
m_nE = 0;
|
||||||
|
m_nCCs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph::~Graph()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graph::Allocate(size_t nV, size_t nE)
|
||||||
|
{
|
||||||
|
m_nV = nV;
|
||||||
|
m_edges.reserve(nE);
|
||||||
|
m_vertices.resize(nV);
|
||||||
|
for(size_t i = 0; i < nV; i++)
|
||||||
|
{
|
||||||
|
m_vertices[i].m_name = static_cast<long>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long Graph::AddVertex()
|
||||||
|
{
|
||||||
|
size_t name = m_vertices.size();
|
||||||
|
m_vertices.resize(name+1);
|
||||||
|
m_vertices[name].m_name = static_cast<long>(name);
|
||||||
|
m_nV++;
|
||||||
|
return static_cast<long>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
long Graph::AddEdge(long v1, long v2)
|
||||||
|
{
|
||||||
|
size_t name = m_edges.size();
|
||||||
|
m_edges.push_back(GraphEdge());
|
||||||
|
m_edges[name].m_name = static_cast<long>(name);
|
||||||
|
m_edges[name].m_v1 = v1;
|
||||||
|
m_edges[name].m_v2 = v2;
|
||||||
|
m_vertices[v1].AddEdge(static_cast<long>(name));
|
||||||
|
m_vertices[v2].AddEdge(static_cast<long>(name));
|
||||||
|
m_nE++;
|
||||||
|
return static_cast<long>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graph::DeleteEdge(long name)
|
||||||
|
{
|
||||||
|
if (name < static_cast<long>(m_edges.size()))
|
||||||
|
{
|
||||||
|
long v1 = m_edges[name].m_v1;
|
||||||
|
long v2 = m_edges[name].m_v2;
|
||||||
|
m_edges[name].m_deleted = true;
|
||||||
|
m_vertices[v1].DeleteEdge(name);
|
||||||
|
m_vertices[v2].DeleteEdge(name);
|
||||||
|
m_nE--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool Graph::DeleteVertex(long name)
|
||||||
|
{
|
||||||
|
if (name < static_cast<long>(m_vertices.size()))
|
||||||
|
{
|
||||||
|
m_vertices[name].m_deleted = true;
|
||||||
|
m_vertices[name].m_edges.Clear();
|
||||||
|
m_vertices[name].m_ancestors = std::vector<long>();
|
||||||
|
delete m_vertices[name].m_convexHull;
|
||||||
|
m_vertices[name].m_distPoints.Clear();
|
||||||
|
m_vertices[name].m_boudaryEdges.Clear();
|
||||||
|
m_vertices[name].m_convexHull = 0;
|
||||||
|
m_nV--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool Graph::EdgeCollapse(long v1, long v2)
|
||||||
|
{
|
||||||
|
long edgeToDelete = GetEdgeID(v1, v2);
|
||||||
|
if (edgeToDelete >= 0)
|
||||||
|
{
|
||||||
|
// delete the edge (v1, v2)
|
||||||
|
DeleteEdge(edgeToDelete);
|
||||||
|
// add v2 to v1 ancestors
|
||||||
|
m_vertices[v1].m_ancestors.push_back(v2);
|
||||||
|
// add v2's ancestors to v1's ancestors
|
||||||
|
m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(),
|
||||||
|
m_vertices[v2].m_ancestors.begin(),
|
||||||
|
m_vertices[v2].m_ancestors.end());
|
||||||
|
// update adjacency information
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> & v1Edges = m_vertices[v1].m_edges;
|
||||||
|
long b = -1;
|
||||||
|
long idEdge;
|
||||||
|
for(size_t ed = 0; ed < m_vertices[v2].m_edges.Size(); ++ed)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[v2].m_edges[ed];
|
||||||
|
if (m_edges[idEdge].m_v1 == v2)
|
||||||
|
{
|
||||||
|
b = m_edges[idEdge].m_v2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b = m_edges[idEdge].m_v1;
|
||||||
|
}
|
||||||
|
if (GetEdgeID(v1, b) >= 0)
|
||||||
|
{
|
||||||
|
m_edges[idEdge].m_deleted = true;
|
||||||
|
m_vertices[b].DeleteEdge(idEdge);
|
||||||
|
m_nE--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_edges[idEdge].m_v1 = v1;
|
||||||
|
m_edges[idEdge].m_v2 = b;
|
||||||
|
v1Edges.Insert(idEdge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// delete the vertex v2
|
||||||
|
DeleteVertex(v2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
long Graph::GetEdgeID(long v1, long v2) const
|
||||||
|
{
|
||||||
|
if (v1 < static_cast<long>(m_vertices.size()) && !m_vertices[v1].m_deleted)
|
||||||
|
{
|
||||||
|
long idEdge;
|
||||||
|
for(size_t ed = 0; ed < m_vertices[v1].m_edges.Size(); ++ed)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[v1].m_edges[ed];
|
||||||
|
if ( (m_edges[idEdge].m_v1 == v2) ||
|
||||||
|
(m_edges[idEdge].m_v2 == v2) )
|
||||||
|
{
|
||||||
|
return m_edges[idEdge].m_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graph::Print() const
|
||||||
|
{
|
||||||
|
std::cout << "-----------------------------" << std::endl;
|
||||||
|
std::cout << "vertices (" << m_nV << ")" << std::endl;
|
||||||
|
for (size_t v = 0; v < m_vertices.size(); ++v)
|
||||||
|
{
|
||||||
|
const GraphVertex & currentVertex = m_vertices[v];
|
||||||
|
if (!m_vertices[v].m_deleted)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::cout << currentVertex.m_name << "\t";
|
||||||
|
long idEdge;
|
||||||
|
for(size_t ed = 0; ed < currentVertex.m_edges.Size(); ++ed)
|
||||||
|
{
|
||||||
|
idEdge = currentVertex.m_edges[ed];
|
||||||
|
std::cout << "(" << m_edges[idEdge].m_v1 << "," << m_edges[idEdge].m_v2 << ") ";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "vertices (" << m_nE << ")" << std::endl;
|
||||||
|
for (size_t e = 0; e < m_edges.size(); ++e)
|
||||||
|
{
|
||||||
|
const GraphEdge & currentEdge = m_edges[e];
|
||||||
|
if (!m_edges[e].m_deleted)
|
||||||
|
{
|
||||||
|
std::cout << currentEdge.m_name << "\t("
|
||||||
|
<< m_edges[e].m_v1 << ","
|
||||||
|
<< m_edges[e].m_v2 << ") "<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Graph::Clear()
|
||||||
|
{
|
||||||
|
m_vertices.clear();
|
||||||
|
m_edges.clear();
|
||||||
|
m_nV = 0;
|
||||||
|
m_nE = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long Graph::ExtractCCs()
|
||||||
|
{
|
||||||
|
// all CCs to -1
|
||||||
|
for (size_t v = 0; v < m_vertices.size(); ++v)
|
||||||
|
{
|
||||||
|
if (!m_vertices[v].m_deleted)
|
||||||
|
{
|
||||||
|
m_vertices[v].m_cc = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we get the CCs
|
||||||
|
m_nCCs = 0;
|
||||||
|
long v2 = -1;
|
||||||
|
long idEdge;
|
||||||
|
std::vector<long> temp;
|
||||||
|
for (size_t v = 0; v < m_vertices.size(); ++v)
|
||||||
|
{
|
||||||
|
if (!m_vertices[v].m_deleted && m_vertices[v].m_cc == -1)
|
||||||
|
{
|
||||||
|
m_vertices[v].m_cc = static_cast<long>(m_nCCs);
|
||||||
|
temp.clear();
|
||||||
|
temp.push_back(m_vertices[v].m_name);
|
||||||
|
while (temp.size())
|
||||||
|
{
|
||||||
|
long vertex = temp[temp.size()-1];
|
||||||
|
temp.pop_back();
|
||||||
|
for(size_t ed = 0; ed < m_vertices[vertex].m_edges.Size(); ++ed)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[vertex].m_edges[ed];
|
||||||
|
if (m_edges[idEdge].m_v1 == vertex)
|
||||||
|
{
|
||||||
|
v2 = m_edges[idEdge].m_v2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v2 = m_edges[idEdge].m_v1;
|
||||||
|
}
|
||||||
|
if ( !m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1)
|
||||||
|
{
|
||||||
|
m_vertices[v2].m_cc = static_cast<long>(m_nCCs);
|
||||||
|
temp.push_back(v2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_nCCs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return static_cast<long>(m_nCCs);
|
||||||
|
}
|
||||||
|
}
|
||||||
118
indra/libhacd/hacdGraph.h
Normal file
118
indra/libhacd/hacdGraph.h
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_GRAPH_H
|
||||||
|
#define HACD_GRAPH_H
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include "hacdVector.h"
|
||||||
|
#include "hacdICHull.h"
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include "hacdSArray.h"
|
||||||
|
//#define HACD_PRECOMPUTE_CHULLS
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
class GraphVertex;
|
||||||
|
class GraphEdge;
|
||||||
|
class Graph;
|
||||||
|
class HACD;
|
||||||
|
|
||||||
|
class GraphVertex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool AddEdge(long name)
|
||||||
|
{
|
||||||
|
m_edges.Insert(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool DeleteEdge(long name);
|
||||||
|
GraphVertex();
|
||||||
|
~GraphVertex(){ delete m_convexHull;};
|
||||||
|
private:
|
||||||
|
long m_name;
|
||||||
|
long m_cc;
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_edges;
|
||||||
|
bool m_deleted;
|
||||||
|
std::vector<long> m_ancestors;
|
||||||
|
SArray<DPoint, SARRAY_DEFAULT_MIN_SIZE> m_distPoints;
|
||||||
|
|
||||||
|
Real m_concavity;
|
||||||
|
double m_surf;
|
||||||
|
ICHull * m_convexHull;
|
||||||
|
SArray<unsigned long long, SARRAY_DEFAULT_MIN_SIZE> m_boudaryEdges;
|
||||||
|
|
||||||
|
|
||||||
|
friend class GraphEdge;
|
||||||
|
friend class Graph;
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GraphEdge
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GraphEdge();
|
||||||
|
~GraphEdge()
|
||||||
|
{
|
||||||
|
#ifdef HACD_PRECOMPUTE_CHULLS
|
||||||
|
delete m_convexHull;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
long m_name;
|
||||||
|
long m_v1;
|
||||||
|
long m_v2;
|
||||||
|
double m_concavity;
|
||||||
|
Real m_error;
|
||||||
|
#ifdef HACD_PRECOMPUTE_CHULLS
|
||||||
|
ICHull * m_convexHull;
|
||||||
|
#endif
|
||||||
|
bool m_deleted;
|
||||||
|
|
||||||
|
friend class GraphVertex;
|
||||||
|
friend class Graph;
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Graph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
size_t GetNEdges() const { return m_nE;}
|
||||||
|
size_t GetNVertices() const { return m_nV;}
|
||||||
|
bool EdgeCollapse(long v1, long v2);
|
||||||
|
long AddVertex();
|
||||||
|
long AddEdge(long v1, long v2);
|
||||||
|
bool DeleteEdge(long name);
|
||||||
|
bool DeleteVertex(long name);
|
||||||
|
long GetEdgeID(long v1, long v2) const;
|
||||||
|
void Clear();
|
||||||
|
void Print() const;
|
||||||
|
long ExtractCCs();
|
||||||
|
|
||||||
|
Graph();
|
||||||
|
virtual ~Graph();
|
||||||
|
void Allocate(size_t nV, size_t nE);
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_nCCs;
|
||||||
|
size_t m_nV;
|
||||||
|
size_t m_nE;
|
||||||
|
std::vector<GraphEdge> m_edges;
|
||||||
|
std::vector<GraphVertex> m_vertices;
|
||||||
|
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
1142
indra/libhacd/hacdHACD.cpp
Normal file
1142
indra/libhacd/hacdHACD.cpp
Normal file
File diff suppressed because it is too large
Load Diff
330
indra/libhacd/hacdHACD.h
Normal file
330
indra/libhacd/hacdHACD.h
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_HACD_H
|
||||||
|
#define HACD_HACD_H
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include "hacdVector.h"
|
||||||
|
#include "hacdGraph.h"
|
||||||
|
#include "hacdICHull.h"
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
const double sc_pi = 3.14159265;
|
||||||
|
class HACD;
|
||||||
|
|
||||||
|
// just to be able to set the capcity of the container
|
||||||
|
|
||||||
|
template<class _Ty, class _Container = std::vector<_Ty>, class _Pr = std::less<typename _Container::value_type> >
|
||||||
|
class reservable_priority_queue: public std::priority_queue<_Ty, _Container, _Pr>
|
||||||
|
{
|
||||||
|
typedef typename std::priority_queue<_Ty, _Container, _Pr>::size_type size_type;
|
||||||
|
public:
|
||||||
|
reservable_priority_queue(size_type capacity = 0) { reserve(capacity); };
|
||||||
|
void reserve(size_type capacity) { this->c.reserve(capacity); }
|
||||||
|
size_type capacity() const { return this->c.capacity(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! priority queque element
|
||||||
|
class HACD;
|
||||||
|
class GraphEdgePriorityQueue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
//! @param name edge's id
|
||||||
|
//! @param priority edge's priority
|
||||||
|
GraphEdgePriorityQueue(long name, Real priority)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
m_priority = priority;
|
||||||
|
}
|
||||||
|
//! Destructor
|
||||||
|
~GraphEdgePriorityQueue(void){}
|
||||||
|
private:
|
||||||
|
long m_name; //!< edge name
|
||||||
|
Real m_priority; //!< priority
|
||||||
|
//! Operator < for GraphEdgePQ
|
||||||
|
friend bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs);
|
||||||
|
//! Operator > for GraphEdgePQ
|
||||||
|
friend bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs);
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
inline bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs)
|
||||||
|
{
|
||||||
|
return (lhs.m_priority<rhs.m_priority);
|
||||||
|
}
|
||||||
|
inline bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_priority>rhs.m_priority;
|
||||||
|
}
|
||||||
|
class ICallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void operator()( char const *aMsg, double aProgress, double aConcavity, size_t aVertices) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef ICallback* CallBackFunction;
|
||||||
|
|
||||||
|
//! Provides an implementation of the Hierarchical Approximate Convex Decomposition (HACD) technique described in "A Simple and Efficient Approach for 3D Mesh Approximate Convex Decomposition" Game Programming Gems 8 - Chapter 2.8, p.202. A short version of the chapter was published in ICIP09 and is available at ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf
|
||||||
|
class HACD
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Gives the targeted number of triangles of the decimated mesh
|
||||||
|
//! @return targeted number of triangles of the decimated mesh
|
||||||
|
size_t GetTargetNTrianglesDecimatedMesh() const { return m_targetNTrianglesDecimatedMesh;}
|
||||||
|
//! Sets the targeted number of triangles of the decimated mesh
|
||||||
|
//! @param targeted number of triangles of the decimated mesh
|
||||||
|
void SetNTargetTrianglesDecimatedMesh(size_t targetNTrianglesDecimatedMesh) { m_targetNTrianglesDecimatedMesh = targetNTrianglesDecimatedMesh;}
|
||||||
|
//! Gives the triangles partitionas an array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
|
||||||
|
//! @return triangles partition
|
||||||
|
const long * const GetPartition() const { return m_partition;}
|
||||||
|
//! Sets the scale factor
|
||||||
|
//! @param scale scale factor
|
||||||
|
void SetScaleFactor(double scale) { m_scale = scale;}
|
||||||
|
//! Gives the scale factor
|
||||||
|
//! @return scale factor
|
||||||
|
const double GetScaleFactor() const { return m_scale;}
|
||||||
|
//! Sets the threshold to detect small clusters. The threshold is expressed as a percentage of the total mesh surface (default 0.25%)
|
||||||
|
//! @param smallClusterThreshold threshold to detect small clusters
|
||||||
|
void SetSmallClusterThreshold(double smallClusterThreshold) { m_smallClusterThreshold = smallClusterThreshold;}
|
||||||
|
//! Gives the threshold to detect small clusters. The threshold is expressed as a percentage of the total mesh surface (default 0.25%)
|
||||||
|
//! @return threshold to detect small clusters
|
||||||
|
const double GetSmallClusterThreshold() const { return m_smallClusterThreshold;}
|
||||||
|
//! Sets the call-back function
|
||||||
|
//! @param callBack pointer to the call-back function
|
||||||
|
void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;}
|
||||||
|
//! Gives the call-back function
|
||||||
|
//! @return pointer to the call-back function
|
||||||
|
const CallBackFunction GetCallBack() const { return m_callBack;}
|
||||||
|
|
||||||
|
//! Specifies whether faces points should be added when computing the concavity
|
||||||
|
//! @param addFacesPoints true = faces points should be added
|
||||||
|
void SetAddFacesPoints(bool addFacesPoints) { m_addFacesPoints = addFacesPoints;}
|
||||||
|
//! Specifies wheter faces points should be added when computing the concavity
|
||||||
|
//! @return true = faces points should be added
|
||||||
|
const bool GetAddFacesPoints() const { return m_addFacesPoints;}
|
||||||
|
//! Specifies whether extra points should be added when computing the concavity
|
||||||
|
//! @param addExteraDistPoints true = extra points should be added
|
||||||
|
void SetAddExtraDistPoints(bool addExtraDistPoints) { m_addExtraDistPoints = addExtraDistPoints;}
|
||||||
|
//! Specifies wheter extra points should be added when computing the concavity
|
||||||
|
//! @return true = extra points should be added
|
||||||
|
const bool GetAddExtraDistPoints() const { return m_addExtraDistPoints;}
|
||||||
|
//! Sets the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
|
||||||
|
//! @param points pointer to the input points
|
||||||
|
void SetPoints(Vec3<Real> * points) { m_points = points;}
|
||||||
|
//! Gives the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
|
||||||
|
//! @return pointer to the input points
|
||||||
|
const Vec3<Real> * GetPoints() const { return m_points;}
|
||||||
|
//! Gives the points of the decimated mesh
|
||||||
|
//! @return pointer to the decimated mesh points
|
||||||
|
const Vec3<Real> * GetDecimatedPoints() const { return m_pointsDecimated;}
|
||||||
|
//! Gives the triangles in the decimated mesh
|
||||||
|
//! @return pointer to the decimated mesh triangles
|
||||||
|
const Vec3<long> * GetDecimatedTriangles() const { return m_trianglesDecimated;}
|
||||||
|
//! Gives the number of points in the decimated mesh.
|
||||||
|
//! @return number of points the decimated mesh mesh
|
||||||
|
const size_t GetNDecimatedPoints() const { return m_nPointsDecimated;}
|
||||||
|
//! Gives the number of triangles in the decimated mesh.
|
||||||
|
//! @return number of triangles the decimated mesh
|
||||||
|
const size_t GetNDecimatedTriangles() const { return m_nTrianglesDecimated;}
|
||||||
|
//! Sets the triangles of the input mesh.
|
||||||
|
//! @param triangles points pointer to the input points
|
||||||
|
void SetTriangles(Vec3<long> * triangles) { m_triangles = triangles;}
|
||||||
|
//! Gives the triangles in the input mesh
|
||||||
|
//! @return pointer to the input triangles
|
||||||
|
const Vec3<long> * GetTriangles() const { return m_triangles;}
|
||||||
|
//! Sets the number of points in the input mesh.
|
||||||
|
//! @param nPoints number of points the input mesh
|
||||||
|
void SetNPoints(size_t nPoints) { m_nPoints = nPoints;}
|
||||||
|
//! Gives the number of points in the input mesh.
|
||||||
|
//! @return number of points the input mesh
|
||||||
|
const size_t GetNPoints() const { return m_nPoints;}
|
||||||
|
//! Sets the number of triangles in the input mesh.
|
||||||
|
//! @param nTriangles number of triangles in the input mesh
|
||||||
|
void SetNTriangles(size_t nTriangles) { m_nTriangles = nTriangles;}
|
||||||
|
//! Gives the number of triangles in the input mesh.
|
||||||
|
//! @return number of triangles the input mesh
|
||||||
|
const size_t GetNTriangles() const { return m_nTriangles;}
|
||||||
|
//! Sets the minimum number of clusters to be generated.
|
||||||
|
//! @param nClusters minimum number of clusters
|
||||||
|
void SetNClusters(size_t nClusters) { m_nMinClusters = nClusters;}
|
||||||
|
//! Gives the number of generated clusters.
|
||||||
|
//! @return number of generated clusters
|
||||||
|
const size_t GetNClusters() const { return m_nClusters;}
|
||||||
|
//! Sets the maximum allowed concavity.
|
||||||
|
//! @param concavity maximum concavity
|
||||||
|
void SetConcavity(double concavity) { m_concavity = concavity;}
|
||||||
|
//! Gives the maximum allowed concavity.
|
||||||
|
//! @return maximum concavity
|
||||||
|
double GetConcavity() const { return m_concavity;}
|
||||||
|
//! Sets the maximum allowed distance to get CCs connected.
|
||||||
|
//! @param concavity maximum distance to get CCs connected
|
||||||
|
void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist;}
|
||||||
|
//! Gives the maximum allowed distance to get CCs connected.
|
||||||
|
//! @return maximum distance to get CCs connected
|
||||||
|
double GetConnectDist() const { return m_ccConnectDist;}
|
||||||
|
//! Sets the volume weight.
|
||||||
|
//! @param beta volume weight
|
||||||
|
void SetVolumeWeight(double beta) { m_beta = beta;}
|
||||||
|
//! Gives the volume weight.
|
||||||
|
//! @return volume weight
|
||||||
|
double GetVolumeWeight() const { return m_beta;}
|
||||||
|
//! Sets the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
|
||||||
|
//! @param alpha compacity weight
|
||||||
|
void SetCompacityWeight(double alpha) { m_alpha = alpha;}
|
||||||
|
//! Gives the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
|
||||||
|
//! @return compacity weight
|
||||||
|
double GetCompacityWeight() const { return m_alpha;}
|
||||||
|
//! Sets the maximum number of vertices for each generated convex-hull.
|
||||||
|
//! @param nVerticesPerCH maximum # vertices per CH
|
||||||
|
void SetNVerticesPerCH(size_t nVerticesPerCH) { m_nVerticesPerCH = nVerticesPerCH;}
|
||||||
|
//! Gives the maximum number of vertices for each generated convex-hull.
|
||||||
|
//! @return maximum # vertices per CH
|
||||||
|
const size_t GetNVerticesPerCH() const { return m_nVerticesPerCH;}
|
||||||
|
//! Gives the number of vertices for the cluster number numCH.
|
||||||
|
//! @return number of vertices
|
||||||
|
size_t GetNPointsCH(size_t numCH) const;
|
||||||
|
//! Gives the number of triangles for the cluster number numCH.
|
||||||
|
//! @param numCH cluster's number
|
||||||
|
//! @return number of triangles
|
||||||
|
size_t GetNTrianglesCH(size_t numCH) const;
|
||||||
|
//! Gives the vertices and the triangles of the cluster number numCH.
|
||||||
|
//! @param numCH cluster's number
|
||||||
|
//! @param points pointer to the vector of points to be filled
|
||||||
|
//! @param triangles pointer to the vector of triangles to be filled
|
||||||
|
//! @return true if sucess
|
||||||
|
bool GetCH(size_t numCH, Vec3<Real> * const points, Vec3<long> * const triangles);
|
||||||
|
//! Computes the HACD decomposition.
|
||||||
|
//! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices
|
||||||
|
//! @param exportDistPoints specifies wheter distance points should ne exported or not (used only for debugging).
|
||||||
|
//! @return true if sucess
|
||||||
|
bool Compute(bool fullCH=false, bool exportDistPoints=false);
|
||||||
|
#if 0
|
||||||
|
//! Saves the generated convex-hulls in a VRML 2.0 file.
|
||||||
|
//! @param fileName the output file name
|
||||||
|
//! @param uniColor specifies whether the different convex-hulls should have the same color or not
|
||||||
|
//! @param numCluster specifies the cluster to be saved, if numCluster < 0 export all clusters
|
||||||
|
//! @return true if sucess
|
||||||
|
bool Save(const char * fileName, bool uniColor, long numCluster=-1) const;
|
||||||
|
#endif
|
||||||
|
//! Shifts and scales to the data to have all the coordinates between 0.0 and 1000.0.
|
||||||
|
void NormalizeData();
|
||||||
|
//! Inverse the operations applied by NormalizeData().
|
||||||
|
void DenormalizeData();
|
||||||
|
//! Destructor.
|
||||||
|
~HACD(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Constructor.
|
||||||
|
HACD(HeapManager * heapManager = 0);
|
||||||
|
|
||||||
|
//! Gives the edge index.
|
||||||
|
//! @param a first vertex id
|
||||||
|
//! @param b second vertex id
|
||||||
|
//! @return edge's index
|
||||||
|
static unsigned long long GetEdgeIndex(unsigned long long a, unsigned long long b)
|
||||||
|
{
|
||||||
|
if (a > b) return (a << 32) + b;
|
||||||
|
else return (b << 32) + a;
|
||||||
|
}
|
||||||
|
//! Computes the concavity of a cluster.
|
||||||
|
//! @param ch the cluster's convex-hull
|
||||||
|
//! @param distPoints the cluster's points
|
||||||
|
//! @return cluster's concavity
|
||||||
|
double Concavity(ICHull & ch, std::map<long, DPoint> & distPoints);
|
||||||
|
//! Computes the perimeter of a cluster.
|
||||||
|
//! @param triIndices the cluster's triangles
|
||||||
|
//! @param distPoints the cluster's points
|
||||||
|
//! @return cluster's perimeter
|
||||||
|
double ComputePerimeter(const std::vector<long> & triIndices) const;
|
||||||
|
//! Creates the Graph by associating to each mesh triangle a vertex in the graph and to each couple of adjacent triangles an edge in the graph.
|
||||||
|
void CreateGraph();
|
||||||
|
//! Initializes the graph costs and computes the vertices normals
|
||||||
|
void InitializeDualGraph();
|
||||||
|
//! Computes the cost of an edge
|
||||||
|
//! @param e edge's id
|
||||||
|
void ComputeEdgeCost(size_t e);
|
||||||
|
//! Initializes the priority queue
|
||||||
|
//! @param fast specifies whether fast mode is used
|
||||||
|
//! @return true if success
|
||||||
|
bool InitializePriorityQueue();
|
||||||
|
//! Cleans the intersection between convex-hulls
|
||||||
|
void CleanClusters();
|
||||||
|
//! Computes convex-hulls from partition information
|
||||||
|
//! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices
|
||||||
|
void ComputeConvexHulls(bool fullCH);
|
||||||
|
//! Simplifies the graph
|
||||||
|
//! @param fast specifies whether fast mode is used
|
||||||
|
void Simplify();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vec3<long> * m_trianglesDecimated; //>! pointer the triangles array
|
||||||
|
Vec3<Real> * m_pointsDecimated; //>! pointer the points array
|
||||||
|
Vec3<long> * m_triangles; //>! pointer the triangles array
|
||||||
|
Vec3<Real> * m_points; //>! pointer the points array
|
||||||
|
Vec3<Real> * m_facePoints; //>! pointer to the faces points array
|
||||||
|
Vec3<Real> * m_faceNormals; //>! pointer to the faces normals array
|
||||||
|
Vec3<Real> * m_normals; //>! pointer the normals array
|
||||||
|
Vec3<Real> * m_extraDistPoints; //>! pointer to the faces points array
|
||||||
|
Vec3<Real> * m_extraDistNormals; //>! pointer to the faces normals array
|
||||||
|
size_t m_nTrianglesDecimated; //>! number of triangles in the original mesh
|
||||||
|
size_t m_nPointsDecimated; //>! number of vertices in the original mesh
|
||||||
|
size_t m_nTriangles; //>! number of triangles in the original mesh
|
||||||
|
size_t m_nPoints; //>! number of vertices in the original mesh
|
||||||
|
size_t m_nClusters; //>! number of clusters
|
||||||
|
size_t m_nMinClusters; //>! minimum number of clusters
|
||||||
|
double m_ccConnectDist; //>! maximum allowed distance to connect CCs
|
||||||
|
double m_concavity; //>! maximum concavity
|
||||||
|
double m_alpha; //>! compacity weigth
|
||||||
|
double m_beta; //>! volume weigth
|
||||||
|
double m_gamma; //>! computation cost
|
||||||
|
double m_diag; //>! length of the BB diagonal
|
||||||
|
double m_scale; //>! scale factor used for NormalizeData() and DenormalizeData()
|
||||||
|
double m_flatRegionThreshold; //>! threshhold to control the contirbution of flat regions concavity (default 1% of m_scale)
|
||||||
|
double m_smallClusterThreshold; //>! threshhold to detect small clusters (default 0.25% of the total mesh surface)
|
||||||
|
double m_area; //>! surface area
|
||||||
|
Vec3<Real> m_barycenter; //>! barycenter of the mesh
|
||||||
|
std::vector< long > m_cVertices; //>! array of vertices each belonging to a different cluster
|
||||||
|
ICHull * m_convexHulls; //>! convex-hulls associated with the final HACD clusters
|
||||||
|
Graph m_graph; //>! simplification graph
|
||||||
|
size_t m_nVerticesPerCH; //>! maximum number of vertices per convex-hull
|
||||||
|
reservable_priority_queue<GraphEdgePriorityQueue,
|
||||||
|
std::vector<GraphEdgePriorityQueue>,
|
||||||
|
std::greater<std::vector<GraphEdgePriorityQueue>::value_type> > m_pqueue; //!> priority queue
|
||||||
|
HACD(const HACD & rhs);
|
||||||
|
CallBackFunction m_callBack; //>! call-back function
|
||||||
|
long * m_partition; //>! array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
|
||||||
|
size_t m_targetNTrianglesDecimatedMesh; //>! specifies the target number of triangles in the decimated mesh. If set to 0 no decimation is applied.
|
||||||
|
HeapManager * m_heapManager; //>! Heap Manager
|
||||||
|
bool m_addFacesPoints; //>! specifies whether to add faces points or not
|
||||||
|
bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not
|
||||||
|
|
||||||
|
friend HACD * const CreateHACD(HeapManager * heapManager = 0);
|
||||||
|
friend void DestroyHACD(HACD * const hacd);
|
||||||
|
};
|
||||||
|
inline HACD * const CreateHACD(HeapManager * heapManager)
|
||||||
|
{
|
||||||
|
return new HACD(heapManager);
|
||||||
|
}
|
||||||
|
inline void DestroyHACD(HACD * const hacd)
|
||||||
|
{
|
||||||
|
delete hacd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
1004
indra/libhacd/hacdICHull.cpp
Normal file
1004
indra/libhacd/hacdICHull.cpp
Normal file
File diff suppressed because it is too large
Load Diff
133
indra/libhacd/hacdICHull.h
Normal file
133
indra/libhacd/hacdICHull.h
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_ICHULL_H
|
||||||
|
#define HACD_ICHULL_H
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include "hacdManifoldMesh.h"
|
||||||
|
#include "hacdVector.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include "hacdMicroAllocator.h"
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
class DPoint;
|
||||||
|
class HACD;
|
||||||
|
//! Incremental Convex Hull algorithm (cf. http://maven.smith.edu/~orourke/books/ftp.html ).
|
||||||
|
enum ICHullError
|
||||||
|
{
|
||||||
|
ICHullErrorOK = 0,
|
||||||
|
ICHullErrorCoplanarPoints,
|
||||||
|
ICHullErrorNoVolume,
|
||||||
|
ICHullErrorInconsistent,
|
||||||
|
ICHullErrorNotEnoughPoints
|
||||||
|
};
|
||||||
|
class ICHull
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const double sc_eps;
|
||||||
|
//!
|
||||||
|
HeapManager * const GetHeapManager() const { return m_heapManager;}
|
||||||
|
//!
|
||||||
|
void SetHeapManager(HeapManager * const heapManager)
|
||||||
|
{
|
||||||
|
m_heapManager = heapManager;
|
||||||
|
m_mesh.SetHeapManager(m_heapManager);
|
||||||
|
}
|
||||||
|
//!
|
||||||
|
bool IsFlat() { return m_isFlat;}
|
||||||
|
//!
|
||||||
|
std::map<long, DPoint> * GetDistPoints() const { return m_distPoints;}
|
||||||
|
//!
|
||||||
|
void SetDistPoints(std::map<long, DPoint> * distPoints) { m_distPoints = distPoints;}
|
||||||
|
//! Returns the computed mesh
|
||||||
|
TMMesh & GetMesh() { return m_mesh;}
|
||||||
|
//! Add one point to the convex-hull
|
||||||
|
bool AddPoint(const Vec3<Real> & point) {return AddPoints(&point, 1);}
|
||||||
|
//! Add one point to the convex-hull
|
||||||
|
bool AddPoint(const Vec3<Real> & point, long id);
|
||||||
|
//! Add points to the convex-hull
|
||||||
|
bool AddPoints(const Vec3<Real> * points, size_t nPoints);
|
||||||
|
bool AddPoints(std::vector< Vec3<Real> > points);
|
||||||
|
//!
|
||||||
|
ICHullError Process();
|
||||||
|
//!
|
||||||
|
ICHullError Process(unsigned long nPointsCH);
|
||||||
|
//!
|
||||||
|
double ComputeVolume();
|
||||||
|
//!
|
||||||
|
double ComputeArea();
|
||||||
|
//!
|
||||||
|
bool IsInside(const Vec3<Real> & pt0, const double eps = 0.0);
|
||||||
|
//!
|
||||||
|
double ComputeDistance(long name, const Vec3<Real> & pt, const Vec3<Real> & normal, bool & insideHull, bool updateIncidentPoints);
|
||||||
|
//!
|
||||||
|
const ICHull & operator=(ICHull & rhs);
|
||||||
|
|
||||||
|
//! Constructor
|
||||||
|
ICHull(HeapManager * const heapManager=0);
|
||||||
|
//! Destructor
|
||||||
|
virtual ~ICHull(void) {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up.
|
||||||
|
ICHullError DoubleTriangle();
|
||||||
|
//! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face.
|
||||||
|
CircularListElement<TMMTriangle> * MakeFace(CircularListElement<TMMVertex> * v0,
|
||||||
|
CircularListElement<TMMVertex> * v1,
|
||||||
|
CircularListElement<TMMVertex> * v2,
|
||||||
|
CircularListElement<TMMTriangle> * fold);
|
||||||
|
//!
|
||||||
|
CircularListElement<TMMTriangle> * MakeConeFace(CircularListElement<TMMEdge> * e, CircularListElement<TMMVertex> * v);
|
||||||
|
//!
|
||||||
|
bool ProcessPoint();
|
||||||
|
//!
|
||||||
|
bool ComputePointVolume(double &totalVolume, bool markVisibleFaces);
|
||||||
|
//!
|
||||||
|
bool FindMaxVolumePoint();
|
||||||
|
//!
|
||||||
|
bool CleanEdges();
|
||||||
|
//!
|
||||||
|
bool CleanVertices(unsigned long & addedPoints);
|
||||||
|
//!
|
||||||
|
bool CleanTriangles();
|
||||||
|
//!
|
||||||
|
bool CleanUp(unsigned long & addedPoints);
|
||||||
|
//!
|
||||||
|
bool MakeCCW(CircularListElement<TMMTriangle> * f,
|
||||||
|
CircularListElement<TMMEdge> * e,
|
||||||
|
CircularListElement<TMMVertex> * v);
|
||||||
|
void Clear();
|
||||||
|
private:
|
||||||
|
static const long sc_dummyIndex;
|
||||||
|
static const double sc_distMin;
|
||||||
|
TMMesh m_mesh;
|
||||||
|
std::vector<CircularListElement<TMMEdge> *> m_edgesToDelete;
|
||||||
|
std::vector<CircularListElement<TMMEdge> *> m_edgesToUpdate;
|
||||||
|
std::vector<CircularListElement<TMMTriangle> *> m_trianglesToDelete;
|
||||||
|
std::map<long, DPoint> * m_distPoints;
|
||||||
|
// CircularListElement<TMMVertex> * m_dummyVertex;
|
||||||
|
Vec3<Real> m_normal;
|
||||||
|
bool m_isFlat;
|
||||||
|
HeapManager * m_heapManager;
|
||||||
|
|
||||||
|
ICHull(const ICHull & rhs);
|
||||||
|
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
604
indra/libhacd/hacdManifoldMesh.cpp
Normal file
604
indra/libhacd/hacdManifoldMesh.cpp
Normal file
@@ -0,0 +1,604 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#include "hacdManifoldMesh.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
Material::Material(void)
|
||||||
|
{
|
||||||
|
m_diffuseColor.X() = 0.5;
|
||||||
|
m_diffuseColor.Y() = 0.5;
|
||||||
|
m_diffuseColor.Z() = 0.5;
|
||||||
|
m_specularColor.X() = 0.5;
|
||||||
|
m_specularColor.Y() = 0.5;
|
||||||
|
m_specularColor.Z() = 0.5;
|
||||||
|
m_ambientIntensity = 0.4;
|
||||||
|
m_emissiveColor.X() = 0.0;
|
||||||
|
m_emissiveColor.Y() = 0.0;
|
||||||
|
m_emissiveColor.Z() = 0.0;
|
||||||
|
m_shininess = 0.4;
|
||||||
|
m_transparency = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TMMVertex::TMMVertex(void)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
void TMMVertex::Initialize()
|
||||||
|
{
|
||||||
|
m_name = 0;
|
||||||
|
m_id = 0;
|
||||||
|
m_duplicate = 0;
|
||||||
|
m_onHull = false;
|
||||||
|
m_tag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TMMVertex::~TMMVertex(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
TMMEdge::TMMEdge(void)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
void TMMEdge::Initialize()
|
||||||
|
{
|
||||||
|
m_id = 0;
|
||||||
|
m_triangles[0] = m_triangles[1] = m_newFace = 0;
|
||||||
|
m_vertices[0] = m_vertices[1] = 0;
|
||||||
|
}
|
||||||
|
TMMEdge::~TMMEdge(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void TMMTriangle::Initialize()
|
||||||
|
{
|
||||||
|
m_id = 0;
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
m_edges[i] = 0;
|
||||||
|
m_vertices[0] = 0;
|
||||||
|
}
|
||||||
|
m_visible = false;
|
||||||
|
m_incidentPoints.Initialize();
|
||||||
|
}
|
||||||
|
TMMTriangle::TMMTriangle(void)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
TMMTriangle::~TMMTriangle(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
TMMesh::TMMesh(HeapManager * const heapManager):
|
||||||
|
m_vertices(heapManager),
|
||||||
|
m_edges(heapManager),
|
||||||
|
m_triangles(heapManager)
|
||||||
|
{
|
||||||
|
m_barycenter = Vec3<Real>(0,0,0);
|
||||||
|
m_diag = 1;
|
||||||
|
m_heapManager = heapManager;
|
||||||
|
}
|
||||||
|
TMMesh::~TMMesh(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TMMesh::Print()
|
||||||
|
{
|
||||||
|
size_t nV = m_vertices.GetSize();
|
||||||
|
std::cout << "-----------------------------" << std::endl;
|
||||||
|
std::cout << "vertices (" << nV << ")" << std::endl;
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
const TMMVertex & currentVertex = m_vertices.GetData();
|
||||||
|
std::cout << currentVertex.m_id << ", "
|
||||||
|
<< currentVertex.m_pos.X() << ", "
|
||||||
|
<< currentVertex.m_pos.Y() << ", "
|
||||||
|
<< currentVertex.m_pos.Z() << std::endl;
|
||||||
|
m_vertices.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t nE = m_edges.GetSize();
|
||||||
|
std::cout << "edges (" << nE << ")" << std::endl;
|
||||||
|
for(size_t e = 0; e < nE; e++)
|
||||||
|
{
|
||||||
|
const TMMEdge & currentEdge = m_edges.GetData();
|
||||||
|
const CircularListElement<TMMVertex> * v0 = currentEdge.m_vertices[0];
|
||||||
|
const CircularListElement<TMMVertex> * v1 = currentEdge.m_vertices[1];
|
||||||
|
const CircularListElement<TMMTriangle> * f0 = currentEdge.m_triangles[0];
|
||||||
|
const CircularListElement<TMMTriangle> * f1 = currentEdge.m_triangles[1];
|
||||||
|
|
||||||
|
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ")" << std::endl;
|
||||||
|
std::cout << "-> F0 (" << f0->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
|
<< f0->GetData().m_vertices[1]->GetData().m_name << ", "
|
||||||
|
<< f0->GetData().m_vertices[2]->GetData().m_name <<")" << std::endl;
|
||||||
|
std::cout << "-> F1 (" << f1->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
|
<< f1->GetData().m_vertices[1]->GetData().m_name << ", "
|
||||||
|
<< f1->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl;
|
||||||
|
m_edges.Next();
|
||||||
|
}
|
||||||
|
size_t nT = m_triangles.GetSize();
|
||||||
|
std::cout << "triangles (" << nT << ")" << std::endl;
|
||||||
|
for(size_t t = 0; t < nT; t++)
|
||||||
|
{
|
||||||
|
const TMMTriangle & currentTriangle = m_triangles.GetData();
|
||||||
|
const CircularListElement<TMMVertex> * v0 = currentTriangle.m_vertices[0];
|
||||||
|
const CircularListElement<TMMVertex> * v1 = currentTriangle.m_vertices[1];
|
||||||
|
const CircularListElement<TMMVertex> * v2 = currentTriangle.m_vertices[2];
|
||||||
|
const CircularListElement<TMMEdge> * e0 = currentTriangle.m_edges[0];
|
||||||
|
const CircularListElement<TMMEdge> * e1 = currentTriangle.m_edges[1];
|
||||||
|
const CircularListElement<TMMEdge> * e2 = currentTriangle.m_edges[2];
|
||||||
|
|
||||||
|
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ", "<< v2->GetData().m_name << ")" << std::endl;
|
||||||
|
|
||||||
|
std::cout << "-> E0 (" << e0->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
|
<< e0->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
|
||||||
|
std::cout << "-> E1 (" << e1->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
|
<< e1->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
|
||||||
|
std::cout << "-> E2 (" << e2->GetData().m_vertices[0]->GetData().m_name << ", "
|
||||||
|
<< e2->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
|
||||||
|
m_triangles.Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
bool TMMesh::Save(const char *fileName)
|
||||||
|
{
|
||||||
|
std::ofstream fout(fileName);
|
||||||
|
std::cout << "Saving " << fileName << std::endl;
|
||||||
|
if (SaveVRML2(fout))
|
||||||
|
{
|
||||||
|
fout.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TMMesh::SaveVRML2(std::ofstream &fout)
|
||||||
|
{
|
||||||
|
return SaveVRML2(fout, Material());
|
||||||
|
}
|
||||||
|
bool TMMesh::SaveVRML2(std::ofstream &fout, const Material & material)
|
||||||
|
{
|
||||||
|
if (fout.is_open())
|
||||||
|
{
|
||||||
|
size_t nV = m_vertices.GetSize();
|
||||||
|
size_t nT = m_triangles.GetSize();
|
||||||
|
fout <<"#VRML V2.0 utf8" << std::endl;
|
||||||
|
fout <<"" << std::endl;
|
||||||
|
fout <<"# Vertices: " << nV << std::endl;
|
||||||
|
fout <<"# Triangles: " << nT << std::endl;
|
||||||
|
fout <<"" << std::endl;
|
||||||
|
fout <<"Group {" << std::endl;
|
||||||
|
fout <<" children [" << std::endl;
|
||||||
|
fout <<" Shape {" << std::endl;
|
||||||
|
fout <<" appearance Appearance {" << std::endl;
|
||||||
|
fout <<" material Material {" << std::endl;
|
||||||
|
fout <<" diffuseColor " << material.m_diffuseColor.X() << " "
|
||||||
|
<< material.m_diffuseColor.Y() << " "
|
||||||
|
<< material.m_diffuseColor.Z() << std::endl;
|
||||||
|
fout <<" ambientIntensity " << material.m_ambientIntensity << std::endl;
|
||||||
|
fout <<" specularColor " << material.m_specularColor.X() << " "
|
||||||
|
<< material.m_specularColor.Y() << " "
|
||||||
|
<< material.m_specularColor.Z() << std::endl;
|
||||||
|
fout <<" emissiveColor " << material.m_emissiveColor.X() << " "
|
||||||
|
<< material.m_emissiveColor.Y() << " "
|
||||||
|
<< material.m_emissiveColor.Z() << std::endl;
|
||||||
|
fout <<" shininess " << material.m_shininess << std::endl;
|
||||||
|
fout <<" transparency " << material.m_transparency << std::endl;
|
||||||
|
fout <<" }" << std::endl;
|
||||||
|
fout <<" }" << std::endl;
|
||||||
|
fout <<" geometry IndexedFaceSet {" << std::endl;
|
||||||
|
fout <<" ccw TRUE" << std::endl;
|
||||||
|
fout <<" solid TRUE" << std::endl;
|
||||||
|
fout <<" convex TRUE" << std::endl;
|
||||||
|
if (GetNVertices() > 0) {
|
||||||
|
fout <<" coord DEF co Coordinate {" << std::endl;
|
||||||
|
fout <<" point [" << std::endl;
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
TMMVertex & currentVertex = m_vertices.GetData();
|
||||||
|
fout <<" " << currentVertex.m_pos.X() << " "
|
||||||
|
<< currentVertex.m_pos.Y() << " "
|
||||||
|
<< currentVertex.m_pos.Z() << "," << std::endl;
|
||||||
|
currentVertex.m_id = v;
|
||||||
|
m_vertices.Next();
|
||||||
|
}
|
||||||
|
fout <<" ]" << std::endl;
|
||||||
|
fout <<" }" << std::endl;
|
||||||
|
}
|
||||||
|
if (GetNTriangles() > 0) {
|
||||||
|
fout <<" coordIndex [ " << std::endl;
|
||||||
|
for(size_t f = 0; f < nT; f++)
|
||||||
|
{
|
||||||
|
TMMTriangle & currentTriangle = m_triangles.GetData();
|
||||||
|
fout <<" " << currentTriangle.m_vertices[0]->GetData().m_id << ", "
|
||||||
|
<< currentTriangle.m_vertices[1]->GetData().m_id << ", "
|
||||||
|
<< currentTriangle.m_vertices[2]->GetData().m_id << ", -1," << std::endl;
|
||||||
|
m_triangles.Next();
|
||||||
|
}
|
||||||
|
fout <<" ]" << std::endl;
|
||||||
|
}
|
||||||
|
fout <<" }" << std::endl;
|
||||||
|
fout <<" }" << std::endl;
|
||||||
|
fout <<" ]" << std::endl;
|
||||||
|
fout <<"}" << std::endl;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
void TMMesh::GetIFS(Vec3<Real> * const points, Vec3<long> * const triangles)
|
||||||
|
{
|
||||||
|
size_t nV = m_vertices.GetSize();
|
||||||
|
size_t nT = m_triangles.GetSize();
|
||||||
|
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
points[v] = m_vertices.GetData().m_pos;
|
||||||
|
m_vertices.GetData().m_id = v;
|
||||||
|
m_vertices.Next();
|
||||||
|
}
|
||||||
|
for(size_t f = 0; f < nT; f++)
|
||||||
|
{
|
||||||
|
TMMTriangle & currentTriangle = m_triangles.GetData();
|
||||||
|
triangles[f].X() = static_cast<long>(currentTriangle.m_vertices[0]->GetData().m_id);
|
||||||
|
triangles[f].Y() = static_cast<long>(currentTriangle.m_vertices[1]->GetData().m_id);
|
||||||
|
triangles[f].Z() = static_cast<long>(currentTriangle.m_vertices[2]->GetData().m_id);
|
||||||
|
m_triangles.Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void TMMesh::Clear()
|
||||||
|
{
|
||||||
|
m_vertices.Clear();
|
||||||
|
m_edges.Clear();
|
||||||
|
m_triangles.Clear();
|
||||||
|
}
|
||||||
|
void TMMesh::Copy(TMMesh & mesh)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
// updating the id's
|
||||||
|
size_t nV = mesh.m_vertices.GetSize();
|
||||||
|
size_t nE = mesh. m_edges.GetSize();
|
||||||
|
size_t nT = mesh.m_triangles.GetSize();
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
mesh.m_vertices.GetData().m_id = v;
|
||||||
|
mesh.m_vertices.Next();
|
||||||
|
}
|
||||||
|
for(size_t e = 0; e < nE; e++)
|
||||||
|
{
|
||||||
|
mesh.m_edges.GetData().m_id = e;
|
||||||
|
mesh.m_edges.Next();
|
||||||
|
|
||||||
|
}
|
||||||
|
for(size_t f = 0; f < nT; f++)
|
||||||
|
{
|
||||||
|
mesh.m_triangles.GetData().m_id = f;
|
||||||
|
mesh.m_triangles.Next();
|
||||||
|
}
|
||||||
|
// copying data
|
||||||
|
m_vertices = mesh.m_vertices;
|
||||||
|
m_edges = mesh.m_edges;
|
||||||
|
m_triangles = mesh.m_triangles;
|
||||||
|
m_heapManager = mesh.m_heapManager;
|
||||||
|
|
||||||
|
// generating mapping
|
||||||
|
CircularListElement<TMMVertex> ** vertexMap = new CircularListElement<TMMVertex> * [nV];
|
||||||
|
CircularListElement<TMMEdge> ** edgeMap = new CircularListElement<TMMEdge> * [nE];
|
||||||
|
CircularListElement<TMMTriangle> ** triangleMap = new CircularListElement<TMMTriangle> * [nT];
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
vertexMap[v] = m_vertices.GetHead();
|
||||||
|
m_vertices.Next();
|
||||||
|
}
|
||||||
|
for(size_t e = 0; e < nE; e++)
|
||||||
|
{
|
||||||
|
edgeMap[e] = m_edges.GetHead();
|
||||||
|
m_edges.Next();
|
||||||
|
}
|
||||||
|
for(size_t f = 0; f < nT; f++)
|
||||||
|
{
|
||||||
|
triangleMap[f] = m_triangles.GetHead();
|
||||||
|
m_triangles.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// updating pointers
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
if (vertexMap[v]->GetData().m_duplicate)
|
||||||
|
{
|
||||||
|
vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(size_t e = 0; e < nE; e++)
|
||||||
|
{
|
||||||
|
if (edgeMap[e]->GetData().m_newFace)
|
||||||
|
{
|
||||||
|
edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id];
|
||||||
|
}
|
||||||
|
if (nT > 0)
|
||||||
|
{
|
||||||
|
for(int f = 0; f < 2; f++)
|
||||||
|
{
|
||||||
|
if (edgeMap[e]->GetData().m_triangles[f])
|
||||||
|
{
|
||||||
|
edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int v = 0; v < 2; v++)
|
||||||
|
{
|
||||||
|
if (edgeMap[e]->GetData().m_vertices[v])
|
||||||
|
{
|
||||||
|
edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(size_t f = 0; f < nT; f++)
|
||||||
|
{
|
||||||
|
if (nE > 0)
|
||||||
|
{
|
||||||
|
for(int e = 0; e < 3; e++)
|
||||||
|
{
|
||||||
|
if (triangleMap[f]->GetData().m_edges[e])
|
||||||
|
{
|
||||||
|
triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
if (triangleMap[f]->GetData().m_vertices[v])
|
||||||
|
{
|
||||||
|
triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete [] vertexMap;
|
||||||
|
delete [] edgeMap;
|
||||||
|
delete [] triangleMap;
|
||||||
|
|
||||||
|
}
|
||||||
|
long IntersectRayTriangle(const Vec3<double> & P0, const Vec3<double> & dir,
|
||||||
|
const Vec3<double> & V0, const Vec3<double> & V1,
|
||||||
|
const Vec3<double> & V2, double &t)
|
||||||
|
{
|
||||||
|
const double EPS = 1e-9;
|
||||||
|
const double EPS1 = 1e-6;
|
||||||
|
t = 0.0;
|
||||||
|
Vec3<double> edge1, edge2, edge3;
|
||||||
|
double det;
|
||||||
|
edge1 = V1 - V2;
|
||||||
|
edge2 = V2 - V0;
|
||||||
|
Vec3<double> pvec = dir ^ edge2;
|
||||||
|
det = edge1 * pvec;
|
||||||
|
if (det < EPS && det > -EPS)
|
||||||
|
return 0;
|
||||||
|
Vec3<double> tvec = P0 - V0;
|
||||||
|
Vec3<double> qvec = tvec ^ edge1;
|
||||||
|
t = (edge2 * qvec) / det;
|
||||||
|
if (t < 0.0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
edge3 = V0 - V1;
|
||||||
|
Vec3<double> I(P0 + t * dir);
|
||||||
|
Vec3<double> s0 = (I-V0) ^ edge3;
|
||||||
|
Vec3<double> s1 = (I-V1) ^ edge1;
|
||||||
|
Vec3<double> s2 = (I-V2) ^ edge2;
|
||||||
|
|
||||||
|
Vec3<double> normal = edge1 ^ edge2;
|
||||||
|
double diff = normal.GetNorm() - s0.GetNorm() - s1.GetNorm() - s2.GetNorm();
|
||||||
|
|
||||||
|
if (diff < EPS1 && diff > -EPS1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IntersectLineLine(const Vec3<double> & p1, const Vec3<double> & p2,
|
||||||
|
const Vec3<double> & p3, const Vec3<double> & p4,
|
||||||
|
Vec3<double> & pa, Vec3<double> & pb,
|
||||||
|
double & mua, double & mub)
|
||||||
|
{
|
||||||
|
Vec3<double> p13,p43,p21;
|
||||||
|
double d1343,d4321,d1321,d4343,d2121;
|
||||||
|
double numer,denom;
|
||||||
|
|
||||||
|
p13.X() = p1.X() - p3.X();
|
||||||
|
p13.Y() = p1.Y() - p3.Y();
|
||||||
|
p13.Z() = p1.Z() - p3.Z();
|
||||||
|
p43.X() = p4.X() - p3.X();
|
||||||
|
p43.Y() = p4.Y() - p3.Y();
|
||||||
|
p43.Z() = p4.Z() - p3.Z();
|
||||||
|
if (p43.X()==0.0 && p43.Y()==0.0 && p43.Z()==0.0)
|
||||||
|
return false;
|
||||||
|
p21.X() = p2.X() - p1.X();
|
||||||
|
p21.Y() = p2.Y() - p1.Y();
|
||||||
|
p21.Z() = p2.Z() - p1.Z();
|
||||||
|
if (p21.X()==0.0 && p21.Y()==0.0 && p21.Z()==0.0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
|
||||||
|
d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z();
|
||||||
|
d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z();
|
||||||
|
d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z();
|
||||||
|
d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
|
||||||
|
|
||||||
|
denom = d2121 * d4343 - d4321 * d4321;
|
||||||
|
if (denom==0.0)
|
||||||
|
return false;
|
||||||
|
numer = d1343 * d4321 - d1321 * d4343;
|
||||||
|
|
||||||
|
mua = numer / denom;
|
||||||
|
mub = (d1343 + d4321 * (mua)) / d4343;
|
||||||
|
|
||||||
|
pa.X() = p1.X() + mua * p21.X();
|
||||||
|
pa.Y() = p1.Y() + mua * p21.Y();
|
||||||
|
pa.Z() = p1.Z() + mua * p21.Z();
|
||||||
|
pb.X() = p3.X() + mub * p43.X();
|
||||||
|
pb.Y() = p3.Y() + mub * p43.Y();
|
||||||
|
pb.Z() = p3.Z() + mub * p43.Z();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
long IntersectRayTriangle2(const Vec3<double> & P0, const Vec3<double> & dir,
|
||||||
|
const Vec3<double> & V0, const Vec3<double> & V1,
|
||||||
|
const Vec3<double> & V2, double &r)
|
||||||
|
{
|
||||||
|
Vec3<double> u, v, n; // triangle vectors
|
||||||
|
Vec3<double> w0, w; // ray vectors
|
||||||
|
double a, b; // params to calc ray-plane intersect
|
||||||
|
|
||||||
|
// get triangle edge vectors and plane normal
|
||||||
|
u = V1 - V0;
|
||||||
|
v = V2 - V0;
|
||||||
|
n = u ^ v; // cross product
|
||||||
|
if (n.GetNorm() == 0.0) // triangle is degenerate
|
||||||
|
return -1; // do not deal with this case
|
||||||
|
|
||||||
|
w0 = P0 - V0;
|
||||||
|
a = - n * w0;
|
||||||
|
b = n * dir;
|
||||||
|
if (fabs(b) <= 0.0) { // ray is parallel to triangle plane
|
||||||
|
if (a == 0.0) // ray lies in triangle plane
|
||||||
|
return 2;
|
||||||
|
else return 0; // ray disjoint from plane
|
||||||
|
}
|
||||||
|
|
||||||
|
// get intersect point of ray with triangle plane
|
||||||
|
r = a / b;
|
||||||
|
if (r < 0.0) // ray goes away from triangle
|
||||||
|
return 0; // => no intersect
|
||||||
|
// for a segment, also test if (r > 1.0) => no intersect
|
||||||
|
|
||||||
|
Vec3<double> I = P0 + r * dir; // intersect point of ray and plane
|
||||||
|
|
||||||
|
// is I inside T?
|
||||||
|
double uu, uv, vv, wu, wv, D;
|
||||||
|
uu = u * u;
|
||||||
|
uv = u * v;
|
||||||
|
vv = v * v;
|
||||||
|
w = I - V0;
|
||||||
|
wu = w * u;
|
||||||
|
wv = w * v;
|
||||||
|
D = uv * uv - uu * vv;
|
||||||
|
|
||||||
|
// get and test parametric coords
|
||||||
|
double s, t;
|
||||||
|
s = (uv * wv - vv * wu) / D;
|
||||||
|
if (s < 0.0 || s > 1.0) // I is outside T
|
||||||
|
return 0;
|
||||||
|
t = (uv * wu - uu * wv) / D;
|
||||||
|
if (t < 0.0 || (s + t) > 1.0) // I is outside T
|
||||||
|
return 0;
|
||||||
|
return 1; // I is in T
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TMMesh::CheckConsistancy()
|
||||||
|
{
|
||||||
|
size_t nE = m_edges.GetSize();
|
||||||
|
size_t nT = m_triangles.GetSize();
|
||||||
|
for(size_t e = 0; e < nE; e++)
|
||||||
|
{
|
||||||
|
for(int f = 0; f < 2; f++)
|
||||||
|
{
|
||||||
|
if (!m_edges.GetHead()->GetData().m_triangles[f])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_edges.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t f = 0; f < nT; f++)
|
||||||
|
{
|
||||||
|
for(int e = 0; e < 3; e++)
|
||||||
|
{
|
||||||
|
int found = 0;
|
||||||
|
for(int k = 0; k < 2; k++)
|
||||||
|
{
|
||||||
|
if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead())
|
||||||
|
{
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found != 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_triangles.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool TMMesh::Normalize()
|
||||||
|
{
|
||||||
|
size_t nV = m_vertices.GetSize();
|
||||||
|
if (nV == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_barycenter = m_vertices.GetHead()->GetData().m_pos;
|
||||||
|
Vec3<Real> min = m_barycenter;
|
||||||
|
Vec3<Real> max = m_barycenter;
|
||||||
|
Real x, y, z;
|
||||||
|
for(size_t v = 1; v < nV; v++)
|
||||||
|
{
|
||||||
|
m_barycenter += m_vertices.GetHead()->GetData().m_pos;
|
||||||
|
x = m_vertices.GetHead()->GetData().m_pos.X();
|
||||||
|
y = m_vertices.GetHead()->GetData().m_pos.Y();
|
||||||
|
z = m_vertices.GetHead()->GetData().m_pos.Z();
|
||||||
|
if ( x < min.X()) min.X() = x;
|
||||||
|
else if ( x > max.X()) max.X() = x;
|
||||||
|
if ( y < min.Y()) min.Y() = y;
|
||||||
|
else if ( y > max.Y()) max.Y() = y;
|
||||||
|
if ( z < min.Z()) min.Z() = z;
|
||||||
|
else if ( z > max.Z()) max.Z() = z;
|
||||||
|
m_vertices.Next();
|
||||||
|
}
|
||||||
|
m_barycenter /= static_cast<Real>(nV);
|
||||||
|
m_diag = static_cast<Real>(0.001 * (max-min).GetNorm());
|
||||||
|
const Real invDiag = static_cast<Real>(1.0 / m_diag);
|
||||||
|
if (m_diag != 0.0)
|
||||||
|
{
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
m_vertices.GetHead()->GetData().m_pos = (m_vertices.GetHead()->GetData().m_pos - m_barycenter) * invDiag;
|
||||||
|
m_vertices.Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool TMMesh::Denormalize()
|
||||||
|
{
|
||||||
|
size_t nV = m_vertices.GetSize();
|
||||||
|
if (nV == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_diag != 0.0)
|
||||||
|
{
|
||||||
|
for(size_t v = 0; v < nV; v++)
|
||||||
|
{
|
||||||
|
m_vertices.GetHead()->GetData().m_pos = m_vertices.GetHead()->GetData().m_pos * m_diag + m_barycenter;
|
||||||
|
m_vertices.Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
269
indra/libhacd/hacdManifoldMesh.h
Normal file
269
indra/libhacd/hacdManifoldMesh.h
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_MANIFOLD_MESH_H
|
||||||
|
#define HACD_MANIFOLD_MESH_H
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include "hacdCircularList.h"
|
||||||
|
#include "hacdVector.h"
|
||||||
|
#include "hacdSArray.h"
|
||||||
|
#include <set>
|
||||||
|
#include "hacdMicroAllocator.h"
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
class TMMTriangle;
|
||||||
|
class TMMEdge;
|
||||||
|
class TMMesh;
|
||||||
|
class ICHull;
|
||||||
|
class HACD;
|
||||||
|
|
||||||
|
class DPoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DPoint(long name=0, Real dist=0, bool computed=false, bool distOnly=false)
|
||||||
|
:m_name(name),
|
||||||
|
m_dist(dist),
|
||||||
|
m_computed(computed),
|
||||||
|
m_distOnly(distOnly){};
|
||||||
|
~DPoint(){};
|
||||||
|
private:
|
||||||
|
long m_name;
|
||||||
|
Real m_dist;
|
||||||
|
bool m_computed;
|
||||||
|
bool m_distOnly;
|
||||||
|
friend class TMMTriangle;
|
||||||
|
friend class TMMesh;
|
||||||
|
friend class GraphVertex;
|
||||||
|
friend class GraphEdge;
|
||||||
|
friend class Graph;
|
||||||
|
friend class ICHull;
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Vertex data structure used in a triangular manifold mesh (TMM).
|
||||||
|
class TMMVertex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Initialize();
|
||||||
|
TMMVertex(void);
|
||||||
|
~TMMVertex(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vec3<Real> m_pos;
|
||||||
|
long m_name;
|
||||||
|
size_t m_id;
|
||||||
|
CircularListElement<TMMEdge> * m_duplicate; // pointer to incident cone edge (or NULL)
|
||||||
|
bool m_onHull;
|
||||||
|
bool m_tag;
|
||||||
|
TMMVertex(const TMMVertex & rhs);
|
||||||
|
|
||||||
|
friend class HACD;
|
||||||
|
friend class ICHull;
|
||||||
|
friend class TMMesh;
|
||||||
|
friend class TMMTriangle;
|
||||||
|
friend class TMMEdge;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Edge data structure used in a triangular manifold mesh (TMM).
|
||||||
|
class TMMEdge
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Initialize();
|
||||||
|
TMMEdge(void);
|
||||||
|
~TMMEdge(void);
|
||||||
|
private:
|
||||||
|
size_t m_id;
|
||||||
|
CircularListElement<TMMTriangle> * m_triangles[2];
|
||||||
|
CircularListElement<TMMVertex> * m_vertices[2];
|
||||||
|
CircularListElement<TMMTriangle> * m_newFace;
|
||||||
|
|
||||||
|
|
||||||
|
TMMEdge(const TMMEdge & rhs);
|
||||||
|
|
||||||
|
friend class HACD;
|
||||||
|
friend class ICHull;
|
||||||
|
friend class TMMTriangle;
|
||||||
|
friend class TMMVertex;
|
||||||
|
friend class TMMesh;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Triangle data structure used in a triangular manifold mesh (TMM).
|
||||||
|
class TMMTriangle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Initialize();
|
||||||
|
TMMTriangle(void);
|
||||||
|
~TMMTriangle(void);
|
||||||
|
private:
|
||||||
|
size_t m_id;
|
||||||
|
CircularListElement<TMMEdge> * m_edges[3];
|
||||||
|
CircularListElement<TMMVertex> * m_vertices[3];
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_incidentPoints;
|
||||||
|
bool m_visible;
|
||||||
|
|
||||||
|
TMMTriangle(const TMMTriangle & rhs);
|
||||||
|
|
||||||
|
friend class HACD;
|
||||||
|
friend class ICHull;
|
||||||
|
friend class TMMesh;
|
||||||
|
friend class TMMVertex;
|
||||||
|
friend class TMMEdge;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Material(void);
|
||||||
|
~Material(void){}
|
||||||
|
// private:
|
||||||
|
Vec3<double> m_diffuseColor;
|
||||||
|
double m_ambientIntensity;
|
||||||
|
Vec3<double> m_specularColor;
|
||||||
|
Vec3<double> m_emissiveColor;
|
||||||
|
double m_shininess;
|
||||||
|
double m_transparency;
|
||||||
|
|
||||||
|
friend class TMMesh;
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! triangular manifold mesh data structure.
|
||||||
|
class TMMesh
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//!
|
||||||
|
HeapManager * const GetHeapManager() const { return m_heapManager;}
|
||||||
|
//!
|
||||||
|
void SetHeapManager(HeapManager * const heapManager)
|
||||||
|
{
|
||||||
|
m_heapManager = heapManager;
|
||||||
|
m_vertices.SetHeapManager(m_heapManager);
|
||||||
|
m_edges.SetHeapManager(m_heapManager);
|
||||||
|
m_triangles.SetHeapManager(m_heapManager);
|
||||||
|
}
|
||||||
|
//! Returns the number of vertices>
|
||||||
|
inline size_t GetNVertices() const { return m_vertices.GetSize();}
|
||||||
|
//! Returns the number of edges
|
||||||
|
inline size_t GetNEdges() const { return m_edges.GetSize();}
|
||||||
|
//! Returns the number of triangles
|
||||||
|
inline size_t GetNTriangles() const { return m_triangles.GetSize();}
|
||||||
|
//! Returns the vertices circular list
|
||||||
|
inline const CircularList<TMMVertex> & GetVertices() const { return m_vertices;}
|
||||||
|
//! Returns the edges circular list
|
||||||
|
inline const CircularList<TMMEdge> & GetEdges() const { return m_edges;}
|
||||||
|
//! Returns the triangles circular list
|
||||||
|
inline const CircularList<TMMTriangle> & GetTriangles() const { return m_triangles;}
|
||||||
|
//! Returns the vertices circular list
|
||||||
|
inline CircularList<TMMVertex> & GetVertices() { return m_vertices;}
|
||||||
|
//! Returns the edges circular list
|
||||||
|
inline CircularList<TMMEdge> & GetEdges() { return m_edges;}
|
||||||
|
//! Returns the triangles circular list
|
||||||
|
inline CircularList<TMMTriangle> & GetTriangles() { return m_triangles;}
|
||||||
|
//! Add vertex to the mesh
|
||||||
|
CircularListElement<TMMVertex> * AddVertex() {return m_vertices.Add();}
|
||||||
|
//! Add vertex to the mesh
|
||||||
|
CircularListElement<TMMEdge> * AddEdge() {return m_edges.Add();}
|
||||||
|
//! Add vertex to the mesh
|
||||||
|
CircularListElement<TMMTriangle> * AddTriangle() {return m_triangles.Add();}
|
||||||
|
//! Print mesh information
|
||||||
|
void Print();
|
||||||
|
//!
|
||||||
|
void GetIFS(Vec3<Real> * const points, Vec3<long> * const triangles);
|
||||||
|
#if 0
|
||||||
|
//! Save mesh
|
||||||
|
bool Save(const char *fileName);
|
||||||
|
//! Save mesh to VRML 2.0 format
|
||||||
|
bool SaveVRML2(std::ofstream &fout);
|
||||||
|
//! Save mesh to VRML 2.0 format
|
||||||
|
bool SaveVRML2(std::ofstream &fout, const Material & material);
|
||||||
|
#endif
|
||||||
|
//!
|
||||||
|
void Clear();
|
||||||
|
//!
|
||||||
|
void Copy(TMMesh & mesh);
|
||||||
|
//!
|
||||||
|
bool CheckConsistancy();
|
||||||
|
//!
|
||||||
|
bool Normalize();
|
||||||
|
//!
|
||||||
|
bool Denormalize();
|
||||||
|
//! Constructor
|
||||||
|
TMMesh(HeapManager * const heapManager);
|
||||||
|
//! Destructor
|
||||||
|
virtual ~TMMesh(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CircularList<TMMVertex> m_vertices;
|
||||||
|
CircularList<TMMEdge> m_edges;
|
||||||
|
CircularList<TMMTriangle> m_triangles;
|
||||||
|
Real m_diag; //>! length of the BB diagonal
|
||||||
|
Vec3<Real> m_barycenter; //>! barycenter of the mesh
|
||||||
|
HeapManager * m_heapManager;
|
||||||
|
|
||||||
|
// not defined
|
||||||
|
TMMesh(const TMMesh & rhs);
|
||||||
|
friend class ICHull;
|
||||||
|
friend class HACD;
|
||||||
|
};
|
||||||
|
//! IntersectRayTriangle(): intersect a ray with a 3D triangle
|
||||||
|
//! Input: a ray R, and a triangle T
|
||||||
|
//! Output: *I = intersection point (when it exists)
|
||||||
|
//! 0 = disjoint (no intersect)
|
||||||
|
//! 1 = intersect in unique point I1
|
||||||
|
long IntersectRayTriangle( const Vec3<double> & P0, const Vec3<double> & dir,
|
||||||
|
const Vec3<double> & V0, const Vec3<double> & V1,
|
||||||
|
const Vec3<double> & V2, double &t);
|
||||||
|
|
||||||
|
// intersect_RayTriangle(): intersect a ray with a 3D triangle
|
||||||
|
// Input: a ray R, and a triangle T
|
||||||
|
// Output: *I = intersection point (when it exists)
|
||||||
|
// Return: -1 = triangle is degenerate (a segment or point)
|
||||||
|
// 0 = disjoint (no intersect)
|
||||||
|
// 1 = intersect in unique point I1
|
||||||
|
// 2 = are in the same plane
|
||||||
|
long IntersectRayTriangle2(const Vec3<double> & P0, const Vec3<double> & dir,
|
||||||
|
const Vec3<double> & V0, const Vec3<double> & V1,
|
||||||
|
const Vec3<double> & V2, double &r);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate the line segment PaPb that is the shortest route between
|
||||||
|
two lines P1P2 and P3P4. Calculate also the values of mua and mub where
|
||||||
|
Pa = P1 + mua (P2 - P1)
|
||||||
|
Pb = P3 + mub (P4 - P3)
|
||||||
|
Return FALSE if no solution exists.
|
||||||
|
*/
|
||||||
|
bool IntersectLineLine(const Vec3<double> & p1, const Vec3<double> & p2,
|
||||||
|
const Vec3<double> & p3, const Vec3<double> & p4,
|
||||||
|
Vec3<double> & pa, Vec3<double> & pb,
|
||||||
|
double & mua, double &mub);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
684
indra/libhacd/hacdMeshDecimator.cpp
Normal file
684
indra/libhacd/hacdMeshDecimator.cpp
Normal file
@@ -0,0 +1,684 @@
|
|||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include "hacdMeshDecimator.h"
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
MeshDecimator::MeshDecimator(void)
|
||||||
|
{
|
||||||
|
m_triangles = 0;
|
||||||
|
m_points = 0;
|
||||||
|
m_nPoints = 0;
|
||||||
|
m_nInitialTriangles = 0;
|
||||||
|
m_nVertices = 0;
|
||||||
|
m_nTriangles = 0;
|
||||||
|
m_nEdges = 0;
|
||||||
|
m_trianglesTags = 0;
|
||||||
|
m_ecolManifoldConstraint = true;
|
||||||
|
m_callBack = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshDecimator::~MeshDecimator(void)
|
||||||
|
{
|
||||||
|
ReleaseMemory();
|
||||||
|
}
|
||||||
|
void MeshDecimator::ReleaseMemory()
|
||||||
|
{
|
||||||
|
delete [] m_trianglesTags;
|
||||||
|
std::vector< MDVertex > emptyVertices(0);
|
||||||
|
m_vertices.swap(emptyVertices);
|
||||||
|
std::vector<MDEdge> emptyEdges(0);
|
||||||
|
m_edges.swap(emptyEdges);
|
||||||
|
m_pqueue = std::priority_queue<
|
||||||
|
MDEdgePriorityQueue,
|
||||||
|
std::vector<MDEdgePriorityQueue>,
|
||||||
|
std::less<MDEdgePriorityQueue> >();
|
||||||
|
m_triangles = 0;
|
||||||
|
m_points = 0;
|
||||||
|
m_nPoints = 0;
|
||||||
|
m_nInitialTriangles = 0;
|
||||||
|
m_nVertices = 0;
|
||||||
|
m_nTriangles = 0;
|
||||||
|
m_nEdges = 0;
|
||||||
|
m_trianglesTags = 0;
|
||||||
|
}
|
||||||
|
void MeshDecimator::Initialize(size_t nVertices, size_t nTriangles, Vec3<Float> * points, Vec3<long> * triangles)
|
||||||
|
{
|
||||||
|
m_nVertices = nVertices;
|
||||||
|
m_nTriangles = nTriangles;
|
||||||
|
m_nInitialTriangles = nTriangles;
|
||||||
|
m_points = points;
|
||||||
|
m_nPoints = nVertices;
|
||||||
|
m_triangles = triangles;
|
||||||
|
m_trianglesTags = new bool[m_nTriangles];
|
||||||
|
m_edges.reserve(3*m_nTriangles);
|
||||||
|
m_vertices.resize(m_nVertices);
|
||||||
|
for(size_t v = 0; v < m_nVertices; ++v)
|
||||||
|
{
|
||||||
|
m_vertices[v].m_tag = true;
|
||||||
|
}
|
||||||
|
long tri[3];
|
||||||
|
MDEdge edge;
|
||||||
|
edge.m_tag = true;
|
||||||
|
edge.m_onBoundary = true;
|
||||||
|
long nEdges = 0;
|
||||||
|
long idEdge;
|
||||||
|
long nTris = static_cast<long>(m_nTriangles);
|
||||||
|
for(long t = 0; t < nTris; ++t)
|
||||||
|
{
|
||||||
|
tri[0] = m_triangles[t].X();
|
||||||
|
tri[1] = m_triangles[t].Y();
|
||||||
|
tri[2] = m_triangles[t].Z();
|
||||||
|
m_trianglesTags[t] = true;
|
||||||
|
for(int k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
edge.m_v1 = tri[k];
|
||||||
|
edge.m_v2 = tri[(k+1)%3];
|
||||||
|
m_vertices[edge.m_v1].m_triangles.Insert(t);
|
||||||
|
idEdge = GetEdge(edge.m_v1, edge.m_v2);
|
||||||
|
if (idEdge == -1)
|
||||||
|
{
|
||||||
|
m_edges.push_back(edge);
|
||||||
|
m_vertices[edge.m_v1].m_edges.Insert(nEdges);
|
||||||
|
m_vertices[edge.m_v2].m_edges.Insert(nEdges);
|
||||||
|
++nEdges;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_edges[idEdge].m_onBoundary = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_nEdges = static_cast<size_t>(nEdges);
|
||||||
|
for(size_t v = 0; v < m_nVertices; ++v)
|
||||||
|
{
|
||||||
|
m_vertices[v].m_onBoundary = false;
|
||||||
|
for(size_t itE = 0; itE < m_vertices[v].m_edges.Size(); ++itE)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[v].m_edges[itE];
|
||||||
|
if (m_edges[idEdge].m_onBoundary)
|
||||||
|
{
|
||||||
|
m_vertices[v].m_onBoundary = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long MeshDecimator::GetTriangle(long v1, long v2, long v3) const
|
||||||
|
{
|
||||||
|
long i, j, k;
|
||||||
|
long idTriangle;
|
||||||
|
for(size_t it = 0; it < m_vertices[v1].m_triangles.Size(); ++it)
|
||||||
|
{
|
||||||
|
idTriangle = m_vertices[v1].m_triangles[it];
|
||||||
|
i = m_triangles[idTriangle].X();
|
||||||
|
j = m_triangles[idTriangle].Y();
|
||||||
|
k = m_triangles[idTriangle].Z();
|
||||||
|
if ( (i==v1 && j==v2 && k==v3) || (i==v1 && j==v3 && k==v2) ||
|
||||||
|
(i==v2 && j==v1 && k==v3) || (i==v2 && j==v3 && k==v1) ||
|
||||||
|
(i==v3 && j==v2 && k==v1) || (i==v3 && j==v1 && k==v2) )
|
||||||
|
{
|
||||||
|
return idTriangle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
long MeshDecimator::GetEdge(long v1, long v2) const
|
||||||
|
{
|
||||||
|
long idEdge;
|
||||||
|
for(size_t it = 0; it < m_vertices[v1].m_edges.Size(); ++it)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[v1].m_edges[it];
|
||||||
|
if ( (m_edges[idEdge].m_v1==v1 && m_edges[idEdge].m_v2==v2) ||
|
||||||
|
(m_edges[idEdge].m_v1==v2 && m_edges[idEdge].m_v2==v1) )
|
||||||
|
{
|
||||||
|
return idEdge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
void MeshDecimator::EdgeCollapse(long v1, long v2)
|
||||||
|
{
|
||||||
|
long u, w;
|
||||||
|
int shift;
|
||||||
|
long idTriangle;
|
||||||
|
for(size_t itT = 0; itT < m_vertices[v2].m_triangles.Size(); ++itT)
|
||||||
|
{
|
||||||
|
idTriangle = m_vertices[v2].m_triangles[itT];
|
||||||
|
if (m_triangles[idTriangle].X() == v2)
|
||||||
|
{
|
||||||
|
shift = 0;
|
||||||
|
u = m_triangles[idTriangle].Y();
|
||||||
|
w = m_triangles[idTriangle].Z();
|
||||||
|
}
|
||||||
|
else if (m_triangles[idTriangle].Y() == v2)
|
||||||
|
{
|
||||||
|
shift = 1;
|
||||||
|
u = m_triangles[idTriangle].X();
|
||||||
|
w = m_triangles[idTriangle].Z();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shift = 2;
|
||||||
|
u = m_triangles[idTriangle].X();
|
||||||
|
w = m_triangles[idTriangle].Y();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((u == v1) || (w == v1))
|
||||||
|
{
|
||||||
|
m_trianglesTags[idTriangle] = false;
|
||||||
|
m_vertices[u].m_triangles.Erase(idTriangle);
|
||||||
|
m_vertices[w].m_triangles.Erase(idTriangle);
|
||||||
|
m_nTriangles--;
|
||||||
|
}
|
||||||
|
else if (GetTriangle(v1, u, w) == -1)
|
||||||
|
{
|
||||||
|
m_vertices[v1].m_triangles.Insert(idTriangle);
|
||||||
|
m_triangles[idTriangle][shift] = v1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_trianglesTags[idTriangle] = false;
|
||||||
|
m_vertices[u].m_triangles.Erase(idTriangle);
|
||||||
|
m_vertices[w].m_triangles.Erase(idTriangle);
|
||||||
|
m_nTriangles--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long idEdge = 0;
|
||||||
|
for(size_t itE = 0; itE < m_vertices[v2].m_edges.Size(); ++itE)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[v2].m_edges[itE];
|
||||||
|
w = (m_edges[idEdge].m_v1 == v2)? m_edges[idEdge].m_v2 : m_edges[idEdge].m_v1;
|
||||||
|
if (w==v1)
|
||||||
|
{
|
||||||
|
m_edges[idEdge].m_tag = false;
|
||||||
|
m_vertices[w].m_edges.Erase(idEdge);
|
||||||
|
m_nEdges--;
|
||||||
|
}
|
||||||
|
else if ( GetEdge(v1, w) == -1)
|
||||||
|
{
|
||||||
|
if (m_edges[idEdge].m_v1 == v2) m_edges[idEdge].m_v1 = v1;
|
||||||
|
else m_edges[idEdge].m_v2 = v1;
|
||||||
|
m_vertices[v1].m_edges.Insert(idEdge);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_edges[idEdge].m_tag = false;
|
||||||
|
m_vertices[w].m_edges.Erase(idEdge);
|
||||||
|
m_nEdges--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_vertices[v2].m_tag = false;
|
||||||
|
m_nVertices--;
|
||||||
|
// update boundary edges
|
||||||
|
SArray<long, 64> incidentVertices;
|
||||||
|
incidentVertices.PushBack(v1);
|
||||||
|
for(size_t itE = 0; itE < m_vertices[v1].m_edges.Size(); ++itE)
|
||||||
|
{
|
||||||
|
incidentVertices.PushBack((m_edges[idEdge].m_v1!= v1)?m_edges[idEdge].m_v1:m_edges[idEdge].m_v2);
|
||||||
|
idEdge = m_vertices[v1].m_edges[itE];
|
||||||
|
m_edges[idEdge].m_onBoundary = (IsBoundaryEdge(m_edges[idEdge].m_v1, m_edges[idEdge].m_v2) != -1);
|
||||||
|
}
|
||||||
|
// update boundary vertices
|
||||||
|
long idVertex;
|
||||||
|
for(size_t itV = 0; itV < incidentVertices.Size(); ++itV)
|
||||||
|
{
|
||||||
|
idVertex = incidentVertices[itV];
|
||||||
|
m_vertices[idVertex].m_onBoundary = false;
|
||||||
|
for(size_t itE = 0; itE < m_vertices[idVertex].m_edges.Size(); ++itE)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[idVertex].m_edges[itE];
|
||||||
|
if (m_edges[idEdge].m_onBoundary)
|
||||||
|
{
|
||||||
|
m_vertices[idVertex].m_onBoundary = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long MeshDecimator::IsBoundaryEdge(long v1, long v2) const
|
||||||
|
{
|
||||||
|
long commonTri = -1;
|
||||||
|
long itTriangle1, itTriangle2;
|
||||||
|
for(size_t itT1 = 0; itT1 < m_vertices[v1].m_triangles.Size(); ++itT1)
|
||||||
|
{
|
||||||
|
itTriangle1 = m_vertices[v1].m_triangles[itT1];
|
||||||
|
for(size_t itT2 = 0; itT2 < m_vertices[v2].m_triangles.Size(); ++itT2)
|
||||||
|
{
|
||||||
|
itTriangle2 = m_vertices[v2].m_triangles[itT2];
|
||||||
|
if (itTriangle1 == itTriangle2)
|
||||||
|
{
|
||||||
|
if (commonTri == -1)
|
||||||
|
{
|
||||||
|
commonTri = itTriangle1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return commonTri;
|
||||||
|
}
|
||||||
|
bool MeshDecimator::IsBoundaryVertex(long v) const
|
||||||
|
{
|
||||||
|
long idEdge;
|
||||||
|
for(size_t itE = 0; itE < m_vertices[v].m_edges.Size(); ++itE)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[v].m_edges[itE];
|
||||||
|
if ( IsBoundaryEdge(m_edges[idEdge].m_v1, m_edges[idEdge].m_v2) != -1) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshDecimator::GetMeshData(Vec3<Float> * points, Vec3<long> * triangles) const
|
||||||
|
{
|
||||||
|
long * map = new long [m_nPoints];
|
||||||
|
long counter = 0;
|
||||||
|
for (size_t v = 0; v < m_nPoints; ++v)
|
||||||
|
{
|
||||||
|
if ( m_vertices[v].m_tag )
|
||||||
|
{
|
||||||
|
points[counter] = m_points[v];
|
||||||
|
map[v] = counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
counter = 0;
|
||||||
|
for (size_t t = 0; t < m_nInitialTriangles; ++t)
|
||||||
|
{
|
||||||
|
if ( m_trianglesTags[t] )
|
||||||
|
{
|
||||||
|
triangles[counter].X() = map[m_triangles[t].X()];
|
||||||
|
triangles[counter].Y() = map[m_triangles[t].Y()];
|
||||||
|
triangles[counter].Z() = map[m_triangles[t].Z()];
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete [] map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshDecimator::InitializeQEM()
|
||||||
|
{
|
||||||
|
Vec3<Float> coordMin = m_points[0];
|
||||||
|
Vec3<Float> coordMax = m_points[0];
|
||||||
|
Vec3<Float> coord;
|
||||||
|
for (size_t p = 1; p < m_nPoints ; ++p)
|
||||||
|
{
|
||||||
|
coord = m_points[p];
|
||||||
|
if (coordMin.X() > coord.X()) coordMin.X() = coord.X();
|
||||||
|
if (coordMin.Y() > coord.Y()) coordMin.Y() = coord.Y();
|
||||||
|
if (coordMin.Z() > coord.Z()) coordMin.Z() = coord.Z();
|
||||||
|
if (coordMax.X() < coord.X()) coordMax.X() = coord.X();
|
||||||
|
if (coordMax.Y() < coord.Y()) coordMax.Y() = coord.Y();
|
||||||
|
if (coordMax.Z() < coord.Z()) coordMax.Z() = coord.Z();
|
||||||
|
}
|
||||||
|
coordMax -= coordMin;
|
||||||
|
m_diagBB = coordMax.GetNorm();
|
||||||
|
|
||||||
|
long i, j, k;
|
||||||
|
Vec3<Float> n;
|
||||||
|
Float d = 0;
|
||||||
|
Float area = 0;
|
||||||
|
for(size_t v = 0; v < m_nPoints; ++v)
|
||||||
|
{
|
||||||
|
memset(m_vertices[v].m_Q, 0, 10 * sizeof(Float));
|
||||||
|
long idTriangle;
|
||||||
|
for(size_t itT = 0; itT < m_vertices[v].m_triangles.Size(); ++itT)
|
||||||
|
{
|
||||||
|
idTriangle = m_vertices[v].m_triangles[itT];
|
||||||
|
i = m_triangles[idTriangle].X();
|
||||||
|
j = m_triangles[idTriangle].Y();
|
||||||
|
k = m_triangles[idTriangle].Z();
|
||||||
|
n = (m_points[j] - m_points[i])^(m_points[k] - m_points[i]);
|
||||||
|
area = n.GetNorm();
|
||||||
|
n.Normalize();
|
||||||
|
d = - (m_points[v] * n);
|
||||||
|
m_vertices[v].m_Q[0] += area * (n.X() * n.X());
|
||||||
|
m_vertices[v].m_Q[1] += area * (n.X() * n.Y());
|
||||||
|
m_vertices[v].m_Q[2] += area * (n.X() * n.Z());
|
||||||
|
m_vertices[v].m_Q[3] += area * (n.X() * d);
|
||||||
|
m_vertices[v].m_Q[4] += area * (n.Y() * n.Y());
|
||||||
|
m_vertices[v].m_Q[5] += area * (n.Y() * n.Z());
|
||||||
|
m_vertices[v].m_Q[6] += area * (n.Y() * d);
|
||||||
|
m_vertices[v].m_Q[7] += area * (n.Z() * n.Z());
|
||||||
|
m_vertices[v].m_Q[8] += area * (n.Z() * d);
|
||||||
|
m_vertices[v].m_Q[9] += area * (d * d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Vec3<Float> u1, u2;
|
||||||
|
const Float w = static_cast<Float>(1000);
|
||||||
|
long t, v1, v2, v3;
|
||||||
|
for(size_t e = 0; e < m_edges.size(); ++e)
|
||||||
|
{
|
||||||
|
v1 = m_edges[e].m_v1;
|
||||||
|
v2 = m_edges[e].m_v2;
|
||||||
|
t = IsBoundaryEdge(v1, v2);
|
||||||
|
if (t != -1)
|
||||||
|
{
|
||||||
|
if (m_triangles[t].X() != v1 && m_triangles[t].X() != v2) v3 = m_triangles[t].X();
|
||||||
|
else if (m_triangles[t].Y() != v1 && m_triangles[t].Y() != v2) v3 = m_triangles[t].Y();
|
||||||
|
else v3 = m_triangles[t].Z();
|
||||||
|
u1 = m_points[v2] - m_points[v1];
|
||||||
|
u2 = m_points[v3] - m_points[v1];
|
||||||
|
area = w * (u1^u2).GetNorm();
|
||||||
|
u1.Normalize();
|
||||||
|
n = u2 - (u2 * u1) * u1;
|
||||||
|
n.Normalize();
|
||||||
|
|
||||||
|
d = - (m_points[v1] * n);
|
||||||
|
m_vertices[v1].m_Q[0] += area * (n.X() * n.X());
|
||||||
|
m_vertices[v1].m_Q[1] += area * (n.X() * n.Y());
|
||||||
|
m_vertices[v1].m_Q[2] += area * (n.X() * n.Z());
|
||||||
|
m_vertices[v1].m_Q[3] += area * (n.X() * d);
|
||||||
|
m_vertices[v1].m_Q[4] += area * (n.Y() * n.Y());
|
||||||
|
m_vertices[v1].m_Q[5] += area * (n.Y() * n.Z());
|
||||||
|
m_vertices[v1].m_Q[6] += area * (n.Y() * d);
|
||||||
|
m_vertices[v1].m_Q[7] += area * (n.Z() * n.Z());
|
||||||
|
m_vertices[v1].m_Q[8] += area * (n.Z() * d);
|
||||||
|
m_vertices[v1].m_Q[9] += area * (d * d);
|
||||||
|
|
||||||
|
d = - (m_points[v2] * n);
|
||||||
|
m_vertices[v2].m_Q[0] += area * (n.X() * n.X());
|
||||||
|
m_vertices[v2].m_Q[1] += area * (n.X() * n.Y());
|
||||||
|
m_vertices[v2].m_Q[2] += area * (n.X() * n.Z());
|
||||||
|
m_vertices[v2].m_Q[3] += area * (n.X() * d);
|
||||||
|
m_vertices[v2].m_Q[4] += area * (n.Y() * n.Y());
|
||||||
|
m_vertices[v2].m_Q[5] += area * (n.Y() * n.Z());
|
||||||
|
m_vertices[v2].m_Q[6] += area * (n.Y() * d);
|
||||||
|
m_vertices[v2].m_Q[7] += area * (n.Z() * n.Z());
|
||||||
|
m_vertices[v2].m_Q[8] += area * (n.Z() * d);
|
||||||
|
m_vertices[v2].m_Q[9] += area * (d * d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MeshDecimator::InitializePriorityQueue()
|
||||||
|
{
|
||||||
|
double progressOld = -1.0;
|
||||||
|
double progress = 0.0;
|
||||||
|
char msg[1024];
|
||||||
|
double ptgStep = 1.0;
|
||||||
|
long v1, v2;
|
||||||
|
MDEdgePriorityQueue pqEdge;
|
||||||
|
size_t nE = m_edges.size();
|
||||||
|
for(size_t e = 0; e < nE; ++e)
|
||||||
|
{
|
||||||
|
progress = e * 100.0 / nE;
|
||||||
|
if (fabs(progress-progressOld) > ptgStep && m_callBack)
|
||||||
|
{
|
||||||
|
sprintf(msg, "%3.2f %% \t \t \r", progress);
|
||||||
|
(*m_callBack)(msg, progress, 0.0, m_nVertices);
|
||||||
|
progressOld = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_edges[e].m_tag)
|
||||||
|
{
|
||||||
|
v1 = m_edges[e].m_v1;
|
||||||
|
v2 = m_edges[e].m_v2;
|
||||||
|
if ( (!m_ecolManifoldConstraint) || (ManifoldConstraint(v1, v2)))
|
||||||
|
{
|
||||||
|
pqEdge.m_qem = m_edges[e].m_qem = ComputeEdgeCost(v1, v2, m_edges[e].m_pos);
|
||||||
|
pqEdge.m_name = static_cast<long>(e);
|
||||||
|
m_pqueue.push(pqEdge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double MeshDecimator::ComputeEdgeCost(long v1, long v2, Vec3<Float> & newPos) const
|
||||||
|
{
|
||||||
|
double Q[10];
|
||||||
|
double M[12];
|
||||||
|
Vec3<double> pos;
|
||||||
|
for(int i = 0; i < 10; ++i) Q[i] = m_vertices[v1].m_Q[i] + m_vertices[v2].m_Q[i];
|
||||||
|
M[0] = Q[0]; // (0, 0)
|
||||||
|
M[1] = Q[1]; // (0, 1)
|
||||||
|
M[2] = Q[2]; // (0, 2)
|
||||||
|
M[3] = Q[3]; // (0, 3)
|
||||||
|
M[4] = Q[1]; // (1, 0)
|
||||||
|
M[5] = Q[4]; // (1, 1)
|
||||||
|
M[6] = Q[5]; // (1, 2)
|
||||||
|
M[7] = Q[6]; // (1, 3)
|
||||||
|
M[8] = Q[2]; // (2, 0)
|
||||||
|
M[9] = Q[5]; // (2, 1)
|
||||||
|
M[10] = Q[7]; // (2, 2);
|
||||||
|
M[11] = Q[8]; // (2, 3);
|
||||||
|
double det = M[0] * M[5] * M[10] + M[1] * M[6] * M[8] + M[2] * M[4] * M[9]
|
||||||
|
- M[0] * M[6] * M[9] - M[1] * M[4] * M[10]- M[2] * M[5] * M[8];
|
||||||
|
if (det != 0.0)
|
||||||
|
{
|
||||||
|
double d = 1.0 / det;
|
||||||
|
pos.X() = d * (M[1]*M[7]*M[10] + M[2]*M[5]*M[11] + M[3]*M[6]*M[9]
|
||||||
|
-M[1]*M[6]*M[11] - M[2]*M[7]*M[9] - M[3]*M[5]*M[10]);
|
||||||
|
pos.Y() = d * (M[0]*M[6]*M[11] + M[2]*M[7]*M[8] + M[3]*M[4]*M[10]
|
||||||
|
-M[0]*M[7]*M[10] - M[2]*M[4]*M[11] - M[3]*M[6]*M[8]);
|
||||||
|
pos.Z() = d * (M[0]*M[7]*M[9] + M[1]*M[4]*M[11] + M[3]*M[5]*M[8]
|
||||||
|
-M[0]*M[5]*M[11] - M[1]*M[7]*M[8] - M[3]*M[4]*M[9]);
|
||||||
|
newPos.X() = static_cast<Float>(pos.X());
|
||||||
|
newPos.Y() = static_cast<Float>(pos.Y());
|
||||||
|
newPos.Z() = static_cast<Float>(pos.Z());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const Float w = static_cast<Float>(0.5f);
|
||||||
|
newPos = w * m_points[v1] + w * m_points[v2];
|
||||||
|
pos.X() = static_cast<double>(newPos.X());
|
||||||
|
pos.Y() = static_cast<double>(newPos.Y());
|
||||||
|
pos.Z() = static_cast<double>(newPos.Z());
|
||||||
|
}
|
||||||
|
|
||||||
|
double qem = pos.X() * (Q[0] * pos.X() + Q[1] * pos.Y() + Q[2] * pos.Z() + Q[3]) +
|
||||||
|
pos.Y() * (Q[1] * pos.X() + Q[4] * pos.Y() + Q[5] * pos.Z() + Q[6]) +
|
||||||
|
pos.Z() * (Q[2] * pos.X() + Q[5] * pos.Y() + Q[7] * pos.Z() + Q[8]) +
|
||||||
|
(Q[3] * pos.X() + Q[6] * pos.Y() + Q[8] * pos.Z() + Q[9]) ;
|
||||||
|
|
||||||
|
Vec3<Float> d1;
|
||||||
|
Vec3<Float> d2;
|
||||||
|
Vec3<Float> n1;
|
||||||
|
Vec3<Float> n2;
|
||||||
|
Vec3<Float> oldPosV1 = m_points[v1];
|
||||||
|
Vec3<Float> oldPosV2 = m_points[v2];
|
||||||
|
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> triangles = m_vertices[v1].m_triangles;
|
||||||
|
long idTriangle;
|
||||||
|
for(size_t itT = 0; itT < m_vertices[v2].m_triangles.Size(); ++itT)
|
||||||
|
{
|
||||||
|
idTriangle = m_vertices[v2].m_triangles[itT];
|
||||||
|
triangles.Insert(idTriangle);
|
||||||
|
}
|
||||||
|
long a[3];
|
||||||
|
for(size_t itT = 0; itT != triangles.Size(); ++itT)
|
||||||
|
{
|
||||||
|
idTriangle = triangles[itT];
|
||||||
|
a[0] = m_triangles[idTriangle].X();
|
||||||
|
a[1] = m_triangles[idTriangle].Y();
|
||||||
|
a[2] = m_triangles[idTriangle].Z();
|
||||||
|
|
||||||
|
d1 = m_points[a[1]] - m_points[a[0]];
|
||||||
|
d2 = m_points[a[2]] - m_points[a[0]];
|
||||||
|
n1 = d1^d2;
|
||||||
|
|
||||||
|
m_points[v1] = newPos;
|
||||||
|
m_points[v2] = newPos;
|
||||||
|
|
||||||
|
d1 = m_points[a[1]] - m_points[a[0]];
|
||||||
|
d2 = m_points[a[2]] - m_points[a[0]];
|
||||||
|
n2 = d1^d2;
|
||||||
|
|
||||||
|
m_points[v1] = oldPosV1;
|
||||||
|
m_points[v2] = oldPosV2;
|
||||||
|
|
||||||
|
n1.Normalize();
|
||||||
|
n2.Normalize();
|
||||||
|
if (n1*n2 < 0.0)
|
||||||
|
{
|
||||||
|
return std::numeric_limits<double>::max();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( m_ecolManifoldConstraint && !ManifoldConstraint(v1, v2))
|
||||||
|
{
|
||||||
|
return std::numeric_limits<double>::max();
|
||||||
|
}
|
||||||
|
return qem;
|
||||||
|
}
|
||||||
|
bool MeshDecimator::ManifoldConstraint(long v1, long v2) const
|
||||||
|
{
|
||||||
|
std::set<long> vertices;
|
||||||
|
long a, b;
|
||||||
|
long idEdge1;
|
||||||
|
long idEdge2;
|
||||||
|
long idEdgeV1V2 = 0;
|
||||||
|
for(size_t itE1 = 0; itE1 < m_vertices[v1].m_edges.Size(); ++itE1)
|
||||||
|
{
|
||||||
|
idEdge1 = m_vertices[v1].m_edges[itE1];
|
||||||
|
a = (m_edges[idEdge1].m_v1 == v1) ? m_edges[idEdge1].m_v2 : m_edges[idEdge1].m_v1;
|
||||||
|
vertices.insert(a);
|
||||||
|
if (a != v2)
|
||||||
|
{
|
||||||
|
for(size_t itE2 = 0; itE2 < m_vertices[v2].m_edges.Size(); ++itE2)
|
||||||
|
{
|
||||||
|
idEdge2 = m_vertices[v2].m_edges[itE2];
|
||||||
|
b = (m_edges[idEdge2].m_v1 == v2) ? m_edges[idEdge2].m_v2 : m_edges[idEdge2].m_v1;
|
||||||
|
vertices.insert(b);
|
||||||
|
if ( a==b )
|
||||||
|
{
|
||||||
|
if (GetTriangle(v1, v2, a) == -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idEdgeV1V2 = idEdge1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vertices.size() <= 4 || ( m_vertices[v1].m_onBoundary && m_vertices[v2].m_onBoundary && !m_edges[idEdgeV1V2].m_onBoundary))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool MeshDecimator::EdgeCollapse(double & qem)
|
||||||
|
{
|
||||||
|
MDEdgePriorityQueue currentEdge;
|
||||||
|
long v1, v2;
|
||||||
|
bool done = false;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
done = false;
|
||||||
|
if (m_pqueue.size() == 0)
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentEdge = m_pqueue.top();
|
||||||
|
m_pqueue.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( (!m_edges[currentEdge.m_name].m_tag) || (m_edges[currentEdge.m_name].m_qem != currentEdge.m_qem));
|
||||||
|
|
||||||
|
if (done) return false;
|
||||||
|
v1 = m_edges[currentEdge.m_name].m_v1;
|
||||||
|
v2 = m_edges[currentEdge.m_name].m_v2;
|
||||||
|
|
||||||
|
qem = currentEdge.m_qem;
|
||||||
|
EdgeCollapse(v1, v2);
|
||||||
|
m_points[v1] = m_edges[currentEdge.m_name].m_pos ;
|
||||||
|
for(int k = 0; k < 10; k++) m_vertices[v1].m_Q[k] += m_vertices[v2].m_Q[k];
|
||||||
|
|
||||||
|
// Update priority queue
|
||||||
|
long idEdge;
|
||||||
|
long a, b;
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> incidentVertices;
|
||||||
|
for(size_t itE = 0; itE < m_vertices[v1].m_edges.Size(); ++itE)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[v1].m_edges[itE];
|
||||||
|
a = m_edges[idEdge].m_v1;
|
||||||
|
b = m_edges[idEdge].m_v2;
|
||||||
|
incidentVertices.PushBack((a != v1)?a:b);
|
||||||
|
MDEdgePriorityQueue pqEdge;
|
||||||
|
pqEdge.m_qem = m_edges[idEdge].m_qem = ComputeEdgeCost(a, b, m_edges[idEdge].m_pos);
|
||||||
|
pqEdge.m_name = idEdge;
|
||||||
|
m_pqueue.push(pqEdge);
|
||||||
|
}
|
||||||
|
long idVertex;
|
||||||
|
for(size_t itV = 0; itV< incidentVertices.Size(); ++itV)
|
||||||
|
{
|
||||||
|
idVertex = incidentVertices[itV];
|
||||||
|
for(size_t itE = 0; itE < m_vertices[idVertex].m_edges.Size(); ++itE)
|
||||||
|
{
|
||||||
|
idEdge = m_vertices[idVertex].m_edges[itE];
|
||||||
|
a = m_edges[idEdge].m_v1;
|
||||||
|
b = m_edges[idEdge].m_v2;
|
||||||
|
if ( a!=v1 && b!=v1)
|
||||||
|
{
|
||||||
|
MDEdgePriorityQueue pqEdge;
|
||||||
|
pqEdge.m_qem = m_edges[idEdge].m_qem = ComputeEdgeCost(a, b, m_edges[idEdge].m_pos);
|
||||||
|
pqEdge.m_name = idEdge;
|
||||||
|
m_pqueue.push(pqEdge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool MeshDecimator::Decimate(size_t targetNVertices, size_t targetNTriangles, double targetError)
|
||||||
|
{
|
||||||
|
double qem = 0.0;
|
||||||
|
double progressOld = -1.0;
|
||||||
|
double progress = 0.0;
|
||||||
|
char msg[1024];
|
||||||
|
double ptgStep = 1.0;
|
||||||
|
|
||||||
|
if (m_callBack)
|
||||||
|
{
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "+ Mesh" << std::endl;
|
||||||
|
msg << "\t # vertices \t" << m_nPoints << std::endl;
|
||||||
|
msg << "\t # triangles \t" << m_nTriangles << std::endl;
|
||||||
|
msg << "+ Parameters" << std::endl;
|
||||||
|
msg << "\t target # of vertices \t" << targetNVertices << std::endl;
|
||||||
|
msg << "\t target # of triangles \t" << targetNTriangles << std::endl;
|
||||||
|
msg << "\t QEM \t" << targetError << std::endl;
|
||||||
|
(*m_callBack)(msg.str().c_str(), 0.0, 0.0, m_nPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_callBack) (*m_callBack)("+ Initialize QEM \n", 0.0, 0.0, m_nPoints);
|
||||||
|
InitializeQEM();
|
||||||
|
if (m_callBack) (*m_callBack)("+ Initialize priority queue \n", 0.0, 0.0, m_nPoints);
|
||||||
|
InitializePriorityQueue();
|
||||||
|
if (m_callBack) (*m_callBack)("+ Simplification \n", 0.0, 0.0, m_nPoints);
|
||||||
|
double invDiag2 = 1.0 / (m_diagBB * m_diagBB);
|
||||||
|
while((m_pqueue.size() > 0) &&
|
||||||
|
(m_nEdges > 0) &&
|
||||||
|
(m_nVertices > targetNVertices) &&
|
||||||
|
(m_nTriangles > targetNTriangles) &&
|
||||||
|
(qem < targetError))
|
||||||
|
{
|
||||||
|
progress = 100.0 - m_nVertices * 100.0 / m_nPoints;
|
||||||
|
if (fabs(progress-progressOld) > ptgStep && m_callBack)
|
||||||
|
{
|
||||||
|
sprintf(msg, "%3.2f %% V = %lu \t QEM = %f \t \t \r", progress, static_cast<unsigned long>(m_nVertices), sqrt(qem));
|
||||||
|
(*m_callBack)(msg, progress, qem, m_nVertices);
|
||||||
|
progressOld = progress;
|
||||||
|
}
|
||||||
|
if (!EdgeCollapse(qem)) break;
|
||||||
|
qem *= invDiag2;
|
||||||
|
}
|
||||||
|
if (m_callBack)
|
||||||
|
{
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "+ Simplification output" << std::endl;
|
||||||
|
msg << "\t # vertices \t" << m_nVertices << std::endl;
|
||||||
|
msg << "\t # triangles \t" << m_nTriangles << std::endl;
|
||||||
|
msg << "\t QEM \t" << qem << std::endl;
|
||||||
|
(*m_callBack)(msg.str().c_str(), 100.0, qem, m_nVertices);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
116
indra/libhacd/hacdMeshDecimator.h
Normal file
116
indra/libhacd/hacdMeshDecimator.h
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_MESH_DECEMATOR_H
|
||||||
|
#define HACD_MESH_DECEMATOR_H
|
||||||
|
#include <queue>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <limits>
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include "hacdVector.h"
|
||||||
|
#include "hacdSArray.h"
|
||||||
|
#include "hacdHACD.h"
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
typedef double Float;
|
||||||
|
struct MDVertex
|
||||||
|
{
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_edges;
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_triangles;
|
||||||
|
Float m_Q[10];
|
||||||
|
// 0 1 2 3
|
||||||
|
// 4 5 6
|
||||||
|
// 7 8
|
||||||
|
// 9
|
||||||
|
bool m_tag;
|
||||||
|
bool m_onBoundary;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MDEdge
|
||||||
|
{
|
||||||
|
long m_v1;
|
||||||
|
long m_v2;
|
||||||
|
double m_qem;
|
||||||
|
Vec3<Float> m_pos;
|
||||||
|
bool m_onBoundary;
|
||||||
|
bool m_tag;
|
||||||
|
};
|
||||||
|
struct MDEdgePriorityQueue
|
||||||
|
{
|
||||||
|
long m_name;
|
||||||
|
double m_qem;
|
||||||
|
inline friend bool operator<(const MDEdgePriorityQueue & lhs, const MDEdgePriorityQueue & rhs) { return (lhs.m_qem > rhs.m_qem);}
|
||||||
|
inline friend bool operator>(const MDEdgePriorityQueue & lhs, const MDEdgePriorityQueue & rhs) { return (lhs.m_qem < rhs.m_qem);}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MeshDecimator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Sets the call-back function
|
||||||
|
//! @param callBack pointer to the call-back function
|
||||||
|
void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;}
|
||||||
|
//! Gives the call-back function
|
||||||
|
//! @return pointer to the call-back function
|
||||||
|
const CallBackFunction GetCallBack() const { return m_callBack;}
|
||||||
|
|
||||||
|
inline void SetEColManifoldConstraint(bool ecolManifoldConstraint) { m_ecolManifoldConstraint = ecolManifoldConstraint; }
|
||||||
|
inline size_t GetNVertices()const {return m_nVertices;};
|
||||||
|
inline size_t GetNTriangles() const {return m_nTriangles;};
|
||||||
|
inline size_t GetNEdges() const {return m_nEdges;};
|
||||||
|
void GetMeshData(Vec3<Float> * points, Vec3<long> * triangles) const;
|
||||||
|
void ReleaseMemory();
|
||||||
|
void Initialize(size_t nVertices, size_t nTriangles,
|
||||||
|
Vec3<Float> * points,
|
||||||
|
Vec3<long> * triangles);
|
||||||
|
bool Decimate(size_t targetNVertices = 100,
|
||||||
|
size_t targetNTriangles = 0,
|
||||||
|
double targetError = std::numeric_limits<double>::max());
|
||||||
|
|
||||||
|
MeshDecimator(void);
|
||||||
|
~MeshDecimator(void);
|
||||||
|
private :
|
||||||
|
void EdgeCollapse(long v1, long v2);
|
||||||
|
long GetTriangle(long v1, long v2, long v3) const;
|
||||||
|
long GetEdge(long v1, long v2) const;
|
||||||
|
long IsBoundaryEdge(long v1, long v2) const;
|
||||||
|
bool IsBoundaryVertex(long v) const;
|
||||||
|
void InitializePriorityQueue();
|
||||||
|
void InitializeQEM();
|
||||||
|
bool ManifoldConstraint(long v1, long v2) const;
|
||||||
|
double ComputeEdgeCost(long v1, long v2, Vec3<Float> & pos) const;
|
||||||
|
bool EdgeCollapse(double & error);
|
||||||
|
private:
|
||||||
|
Vec3<long> * m_triangles;
|
||||||
|
Vec3<Float> * m_points;
|
||||||
|
size_t m_nPoints;
|
||||||
|
size_t m_nInitialTriangles;
|
||||||
|
size_t m_nVertices;
|
||||||
|
size_t m_nTriangles;
|
||||||
|
size_t m_nEdges;
|
||||||
|
double m_diagBB;
|
||||||
|
std::vector<MDVertex> m_vertices;
|
||||||
|
std::vector<MDEdge> m_edges;
|
||||||
|
std::priority_queue<
|
||||||
|
MDEdgePriorityQueue,
|
||||||
|
std::vector<MDEdgePriorityQueue>,
|
||||||
|
std::less<MDEdgePriorityQueue> > m_pqueue;
|
||||||
|
CallBackFunction m_callBack; //>! call-back function
|
||||||
|
bool * m_trianglesTags;
|
||||||
|
bool m_ecolManifoldConstraint;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
994
indra/libhacd/hacdMicroAllocator.cpp
Normal file
994
indra/libhacd/hacdMicroAllocator.cpp
Normal file
@@ -0,0 +1,994 @@
|
|||||||
|
#include "hacdMicroAllocator.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliffscarab@gmail.com
|
||||||
|
**
|
||||||
|
** If you find this code useful or you are feeling particularily generous I would
|
||||||
|
** ask that you please go to http://www.amillionpixels.us and make a donation
|
||||||
|
** to Troy DeMolay.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** If you wish to contact me you can use the following methods:
|
||||||
|
**
|
||||||
|
** Skype ID: jratcliff63367
|
||||||
|
** email: jratcliffscarab@gmail.com
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** The MIT license:
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and associated documentation files (the "Software"), to deal
|
||||||
|
** in the Software without restriction, including without limitation the rights
|
||||||
|
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
** copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
** to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in all
|
||||||
|
** copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
** 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(LINUX)
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#pragma warning(disable:4100)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
|
||||||
|
//==================================================================================
|
||||||
|
class MemMutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemMutex(void);
|
||||||
|
~MemMutex(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Blocking Lock.
|
||||||
|
void Lock(void);
|
||||||
|
|
||||||
|
// Unlock.
|
||||||
|
void Unlock(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if defined(_WIN32) || defined(_XBOX)
|
||||||
|
CRITICAL_SECTION m_Mutex;
|
||||||
|
#elif defined(__APPLE__) || defined(LINUX)
|
||||||
|
pthread_mutex_t m_Mutex;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//==================================================================================
|
||||||
|
MemMutex::MemMutex(void)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) || defined(_XBOX)
|
||||||
|
InitializeCriticalSection(&m_Mutex);
|
||||||
|
#elif defined(__APPLE__) || defined(LINUX)
|
||||||
|
pthread_mutexattr_t mta;
|
||||||
|
pthread_mutexattr_init(&mta);
|
||||||
|
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
pthread_mutex_init(&m_Mutex, &mta);
|
||||||
|
pthread_mutexattr_destroy(&mta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================
|
||||||
|
MemMutex::~MemMutex(void)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) || defined(_XBOX)
|
||||||
|
DeleteCriticalSection(&m_Mutex);
|
||||||
|
#elif defined(__APPLE__) || defined(LINUX)
|
||||||
|
pthread_mutex_destroy(&m_Mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================
|
||||||
|
// Blocking Lock.
|
||||||
|
//==================================================================================
|
||||||
|
void MemMutex::Lock(void)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) || defined(_XBOX)
|
||||||
|
EnterCriticalSection(&m_Mutex);
|
||||||
|
#elif defined(__APPLE__) || defined(LINUX)
|
||||||
|
pthread_mutex_lock(&m_Mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================
|
||||||
|
// Unlock.
|
||||||
|
//==================================================================================
|
||||||
|
void MemMutex::Unlock(void)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) || defined(_XBOX)
|
||||||
|
LeaveCriticalSection(&m_Mutex);
|
||||||
|
#elif defined(__APPLE__) || defined(LINUX)
|
||||||
|
pthread_mutex_unlock(&m_Mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct ChunkHeader
|
||||||
|
{
|
||||||
|
ChunkHeader *mNextChunk;
|
||||||
|
};
|
||||||
|
|
||||||
|
// interface to add and remove new chunks to the master list.
|
||||||
|
class MicroChunkUpdate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void addMicroChunk(NxU8 *memStart,NxU8 *memEnd,MemoryChunk *chunk) = 0;
|
||||||
|
virtual void removeMicroChunk(MemoryChunk *chunk) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MemoryHeader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemoryHeader *mNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
// a single fixed size chunk for micro-allocations.
|
||||||
|
class MemoryChunk
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemoryChunk(void)
|
||||||
|
{
|
||||||
|
mData = 0;
|
||||||
|
mDataEnd = 0;
|
||||||
|
mUsedCount = 0;
|
||||||
|
mFreeList = 0;
|
||||||
|
mMyHeap = false;
|
||||||
|
mChunkSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU8 * init(NxU8 *chunkBase,NxU32 chunkSize,NxU32 maxChunks)
|
||||||
|
{
|
||||||
|
mChunkSize = chunkSize;
|
||||||
|
mData = chunkBase;
|
||||||
|
mDataEnd = mData+(chunkSize*maxChunks);
|
||||||
|
mFreeList = (MemoryHeader *) mData;
|
||||||
|
MemoryHeader *scan = mFreeList;
|
||||||
|
NxU8 *data = mData;
|
||||||
|
data+=chunkSize;
|
||||||
|
for (NxU32 i=0; i<(maxChunks-1); i++)
|
||||||
|
{
|
||||||
|
MemoryHeader *next = (MemoryHeader *)data;
|
||||||
|
scan->mNext = next;
|
||||||
|
data+=chunkSize;
|
||||||
|
scan = next;
|
||||||
|
}
|
||||||
|
scan->mNext = 0;
|
||||||
|
return mDataEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void * allocate(MicroHeap *heap,NxU32 chunkSize,NxU32 maxChunks,MicroChunkUpdate *update)
|
||||||
|
{
|
||||||
|
void *ret = 0;
|
||||||
|
|
||||||
|
if ( mData == 0 )
|
||||||
|
{
|
||||||
|
mMyHeap = true;
|
||||||
|
mData = (NxU8 *)heap->micro_malloc( chunkSize * maxChunks );
|
||||||
|
init(mData,chunkSize,maxChunks);
|
||||||
|
update->addMicroChunk(mData,mDataEnd,this);
|
||||||
|
}
|
||||||
|
if ( mFreeList )
|
||||||
|
{
|
||||||
|
mUsedCount++;
|
||||||
|
ret = mFreeList;
|
||||||
|
mFreeList = mFreeList->mNext;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void deallocate(void *p,MicroHeap *heap,MicroChunkUpdate *update)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
assert(mUsedCount);
|
||||||
|
NxU8 *s = (NxU8 *)p;
|
||||||
|
assert( s >= mData && s < mDataEnd );
|
||||||
|
#endif
|
||||||
|
MemoryHeader *mh = mFreeList;
|
||||||
|
mFreeList = (MemoryHeader *)p;
|
||||||
|
mFreeList->mNext = mh;
|
||||||
|
mUsedCount--;
|
||||||
|
if ( mUsedCount == 0 && mMyHeap ) // free the heap back to the application if we are done with this.
|
||||||
|
{
|
||||||
|
update->removeMicroChunk(this);
|
||||||
|
heap->micro_free(mData);
|
||||||
|
mMyHeap = false;
|
||||||
|
mData = 0;
|
||||||
|
mDataEnd = 0;
|
||||||
|
mFreeList = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU32 getChunkSize(void) const { return mChunkSize; };
|
||||||
|
|
||||||
|
bool isInside(const NxU8 *p) const
|
||||||
|
{
|
||||||
|
return p>=mData && p < mDataEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mMyHeap;
|
||||||
|
NxU8 *mData;
|
||||||
|
NxU8 *mDataEnd;
|
||||||
|
NxU32 mUsedCount;
|
||||||
|
MemoryHeader *mFreeList;
|
||||||
|
NxU32 mChunkSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFAULT_CHUNKS 32
|
||||||
|
|
||||||
|
class MemoryChunkChunk
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemoryChunkChunk(void)
|
||||||
|
{
|
||||||
|
mNext = 0;
|
||||||
|
mChunkSize = 0;
|
||||||
|
mMaxChunks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~MemoryChunkChunk(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void * allocate(MemoryChunk *¤t,MicroChunkUpdate *update)
|
||||||
|
{
|
||||||
|
void *ret = 0;
|
||||||
|
|
||||||
|
MemoryChunkChunk *scan = this;
|
||||||
|
while ( scan && ret == 0 )
|
||||||
|
{
|
||||||
|
for (NxU32 i=0; i<DEFAULT_CHUNKS; i++)
|
||||||
|
{
|
||||||
|
ret = scan->mChunks[i].allocate(mHeap,mChunkSize,mMaxChunks,update);
|
||||||
|
if ( ret )
|
||||||
|
{
|
||||||
|
current = &scan->mChunks[i];
|
||||||
|
scan = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( scan )
|
||||||
|
scan = scan->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ret )
|
||||||
|
{
|
||||||
|
MemoryChunkChunk *mcc = (MemoryChunkChunk *)mHeap->micro_malloc( sizeof(MemoryChunkChunk) );
|
||||||
|
new ( mcc ) MemoryChunkChunk;
|
||||||
|
MemoryChunkChunk *onext = mNext;
|
||||||
|
mNext = mcc;
|
||||||
|
mcc->mNext = onext;
|
||||||
|
ret = mcc->mChunks[0].allocate(mHeap,mChunkSize,mMaxChunks,update);
|
||||||
|
current = &mcc->mChunks[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU8 * init(NxU8 *chunkBase,NxU32 fixedSize,NxU32 chunkSize,MemoryChunk *¤t,MicroHeap *heap)
|
||||||
|
{
|
||||||
|
mHeap = heap;
|
||||||
|
mChunkSize = chunkSize;
|
||||||
|
mMaxChunks = fixedSize/chunkSize;
|
||||||
|
current = &mChunks[0];
|
||||||
|
chunkBase = mChunks[0].init(chunkBase,chunkSize,mMaxChunks);
|
||||||
|
return chunkBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
MicroHeap *mHeap;
|
||||||
|
NxU32 mChunkSize;
|
||||||
|
NxU32 mMaxChunks;
|
||||||
|
MemoryChunkChunk *mNext;
|
||||||
|
MemoryChunk mChunks[DEFAULT_CHUNKS];
|
||||||
|
};
|
||||||
|
|
||||||
|
class FixedMemory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FixedMemory(void)
|
||||||
|
{
|
||||||
|
mCurrent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * allocate(MicroChunkUpdate *update)
|
||||||
|
{
|
||||||
|
void *ret = mCurrent->allocate(mChunks.mHeap,mChunks.mChunkSize,mChunks.mMaxChunks,update);
|
||||||
|
if ( ret == 0 )
|
||||||
|
{
|
||||||
|
ret = mChunks.allocate(mCurrent,update);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU8 * init(NxU8 *chunkBase,NxU32 chunkSize,NxU32 fixedSize,MicroHeap *heap)
|
||||||
|
{
|
||||||
|
mMemBegin = chunkBase;
|
||||||
|
mMemEnd = chunkBase+fixedSize;
|
||||||
|
mChunks.init(chunkBase,fixedSize,chunkSize,mCurrent,heap);
|
||||||
|
return mMemEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU8 *mMemBegin;
|
||||||
|
NxU8 *mMemEnd;
|
||||||
|
MemoryChunk *mCurrent; // the current memory chunk we are operating in.
|
||||||
|
MemoryChunkChunk mChunks; // the collection of all memory chunks used.
|
||||||
|
};
|
||||||
|
|
||||||
|
class MicroChunk
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void set(NxU8 *memStart,NxU8 *memEnd,MemoryChunk *mc)
|
||||||
|
{
|
||||||
|
mMemStart = memStart;
|
||||||
|
mMemEnd = memEnd;
|
||||||
|
mChunk = mc;
|
||||||
|
mPad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool inside(const NxU8 *p) const
|
||||||
|
{
|
||||||
|
return p >= mMemStart && p < mMemEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU8 *mMemStart;
|
||||||
|
NxU8 *mMemEnd;
|
||||||
|
MemoryChunk *mChunk;
|
||||||
|
NxU8 *mPad; // padding to make it 16 byte aligned.
|
||||||
|
};
|
||||||
|
|
||||||
|
class MyMicroAllocator : public MicroAllocator, public MicroChunkUpdate, public MemMutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyMicroAllocator(MicroHeap *heap,void *baseMem,NxU32 initialSize,NxU32 chunkSize)
|
||||||
|
{
|
||||||
|
mLastMicroChunk = 0;
|
||||||
|
mMicroChunks = 0;
|
||||||
|
mMicroChunkCount = 0;
|
||||||
|
mMaxMicroChunks = 0;
|
||||||
|
mHeap = heap;
|
||||||
|
mChunkSize = chunkSize;
|
||||||
|
|
||||||
|
// 0 through 8 bytes
|
||||||
|
for (NxU32 i=0; i<=8; i++)
|
||||||
|
{
|
||||||
|
mFixedAllocators[i] = &mAlloc[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9 through 16 bytes
|
||||||
|
for (NxU32 i=9; i<=16; i++)
|
||||||
|
{
|
||||||
|
mFixedAllocators[i] = &mAlloc[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 17 through 32 bytes
|
||||||
|
for (NxU32 i=17; i<=32; i++)
|
||||||
|
{
|
||||||
|
mFixedAllocators[i] = &mAlloc[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 33 through 64
|
||||||
|
for (NxU32 i=33; i<=64; i++)
|
||||||
|
{
|
||||||
|
mFixedAllocators[i] = &mAlloc[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 65 through 128
|
||||||
|
for (NxU32 i=65; i<=128; i++)
|
||||||
|
{
|
||||||
|
mFixedAllocators[i] = &mAlloc[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 129 through 255
|
||||||
|
for (NxU32 i=129; i<257; i++)
|
||||||
|
{
|
||||||
|
mFixedAllocators[i] = &mAlloc[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
mBaseMem = (NxU8 *)baseMem;
|
||||||
|
mBaseMemEnd = mBaseMem+initialSize;
|
||||||
|
|
||||||
|
NxU8 *chunkBase = (NxU8 *)baseMem+sizeof(MyMicroAllocator);
|
||||||
|
|
||||||
|
|
||||||
|
chunkBase+=32;
|
||||||
|
NxU64 ptr = (NxU64)chunkBase;
|
||||||
|
ptr = ptr>>4;
|
||||||
|
ptr = ptr<<4; // make sure it is 16 byte aligned.
|
||||||
|
chunkBase = (NxU8 *)ptr;
|
||||||
|
|
||||||
|
mChunkStart = chunkBase;
|
||||||
|
chunkBase = mAlloc[0].init(chunkBase,8,chunkSize,heap);
|
||||||
|
chunkBase = mAlloc[1].init(chunkBase,16,chunkSize,heap);
|
||||||
|
chunkBase = mAlloc[2].init(chunkBase,32,chunkSize,heap);
|
||||||
|
chunkBase = mAlloc[3].init(chunkBase,64,chunkSize,heap);
|
||||||
|
chunkBase = mAlloc[4].init(chunkBase,128,chunkSize,heap);
|
||||||
|
chunkBase = mAlloc[5].init(chunkBase,256,chunkSize,heap);
|
||||||
|
mChunkEnd = chunkBase;
|
||||||
|
|
||||||
|
assert(chunkBase <= mBaseMemEnd );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~MyMicroAllocator(void)
|
||||||
|
{
|
||||||
|
if ( mMicroChunks )
|
||||||
|
{
|
||||||
|
mHeap->micro_free(mMicroChunks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual NxU32 getChunkSize(MemoryChunk *chunk)
|
||||||
|
{
|
||||||
|
return chunk ? chunk->getChunkSize() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have to steal one byte out of every allocation to record the size, so we can efficiently de-allocate it later.
|
||||||
|
virtual void * malloc(size_t size)
|
||||||
|
{
|
||||||
|
void *ret = 0;
|
||||||
|
Lock();
|
||||||
|
assert( size <= 256 );
|
||||||
|
if ( size <= 256 )
|
||||||
|
{
|
||||||
|
ret = mFixedAllocators[size]->allocate(this);
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void free(void *p,MemoryChunk *chunk)
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
chunk->deallocate(p,mHeap,this);
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform a binary search on the sorted list of chunks.
|
||||||
|
MemoryChunk * binarySearchMicroChunks(const NxU8 *p)
|
||||||
|
{
|
||||||
|
MemoryChunk *ret = 0;
|
||||||
|
|
||||||
|
NxU32 low = 0;
|
||||||
|
NxU32 high = mMicroChunkCount;
|
||||||
|
|
||||||
|
while ( low != high )
|
||||||
|
{
|
||||||
|
NxU32 mid = (high-low)/2+low;
|
||||||
|
MicroChunk &chunk = mMicroChunks[mid];
|
||||||
|
if ( chunk.inside(p))
|
||||||
|
{
|
||||||
|
mLastMicroChunk = &chunk;
|
||||||
|
ret = chunk.mChunk;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( p > chunk.mMemEnd )
|
||||||
|
{
|
||||||
|
low = mid+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
high = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual MemoryChunk * isMicroAlloc(const void *p) // returns true if this pointer is handled by the micro-allocator.
|
||||||
|
{
|
||||||
|
MemoryChunk *ret = 0;
|
||||||
|
|
||||||
|
Lock();
|
||||||
|
|
||||||
|
const NxU8 *s = (const NxU8 *)p;
|
||||||
|
|
||||||
|
if ( s >= mChunkStart && s < mChunkEnd )
|
||||||
|
{
|
||||||
|
NxU32 index = (NxU32)(s-mChunkStart)/mChunkSize;
|
||||||
|
assert(index>=0 && index < 6 );
|
||||||
|
ret = &mAlloc[index].mChunks.mChunks[0];
|
||||||
|
assert( ret->isInside(s) );
|
||||||
|
}
|
||||||
|
else if ( mMicroChunkCount )
|
||||||
|
{
|
||||||
|
if ( mLastMicroChunk && mLastMicroChunk->inside(s) )
|
||||||
|
{
|
||||||
|
ret = mLastMicroChunk->mChunk;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( mMicroChunkCount >= 4 )
|
||||||
|
{
|
||||||
|
ret = binarySearchMicroChunks(s);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (ret )
|
||||||
|
{
|
||||||
|
assert( ret->isInside(s) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (NxU32 i=0; i<mMicroChunkCount; i++)
|
||||||
|
{
|
||||||
|
assert( !mMicroChunks[i].inside(s) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (NxU32 i=0; i<mMicroChunkCount; i++)
|
||||||
|
{
|
||||||
|
if ( mMicroChunks[i].inside(s) )
|
||||||
|
{
|
||||||
|
ret = mMicroChunks[i].mChunk;
|
||||||
|
assert( ret->isInside(s) );
|
||||||
|
mLastMicroChunk = &mMicroChunks[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if ( ret )
|
||||||
|
assert( ret->isInside(s) );
|
||||||
|
#endif
|
||||||
|
Unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
MicroHeap * getMicroHeap(void) const { return mHeap; };
|
||||||
|
|
||||||
|
void allocateMicroChunks(void)
|
||||||
|
{
|
||||||
|
if ( mMaxMicroChunks == 0 )
|
||||||
|
{
|
||||||
|
mMaxMicroChunks = 64; // initial reserve.
|
||||||
|
mMicroChunks = (MicroChunk *)mHeap->micro_malloc( sizeof(MicroChunk)*mMaxMicroChunks );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMaxMicroChunks*=2;
|
||||||
|
mMicroChunks = (MicroChunk *)mHeap->micro_realloc( mMicroChunks, sizeof(MicroChunk)*mMaxMicroChunks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform an insertion sort of the new chunk.
|
||||||
|
virtual void addMicroChunk(NxU8 *memStart,NxU8 *memEnd,MemoryChunk *chunk)
|
||||||
|
{
|
||||||
|
if ( mMicroChunkCount >= mMaxMicroChunks )
|
||||||
|
{
|
||||||
|
allocateMicroChunks();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inserted = false;
|
||||||
|
for (NxU32 i=0; i<mMicroChunkCount; i++)
|
||||||
|
{
|
||||||
|
if ( memEnd < mMicroChunks[i].mMemStart )
|
||||||
|
{
|
||||||
|
for (NxU32 j=mMicroChunkCount; j>i; j--)
|
||||||
|
{
|
||||||
|
mMicroChunks[j] = mMicroChunks[j-1];
|
||||||
|
}
|
||||||
|
mMicroChunks[i].set( memStart, memEnd, chunk );
|
||||||
|
mLastMicroChunk = &mMicroChunks[i];
|
||||||
|
mMicroChunkCount++;
|
||||||
|
inserted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !inserted )
|
||||||
|
{
|
||||||
|
mMicroChunks[mMicroChunkCount].set(memStart,memEnd,chunk);
|
||||||
|
mLastMicroChunk = &mMicroChunks[mMicroChunkCount];
|
||||||
|
mMicroChunkCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void removeMicroChunk(MemoryChunk *chunk)
|
||||||
|
{
|
||||||
|
mLastMicroChunk = 0;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
bool removed = false;
|
||||||
|
#endif
|
||||||
|
for (NxU32 i=0; i<mMicroChunkCount; i++)
|
||||||
|
{
|
||||||
|
if ( mMicroChunks[i].mChunk == chunk )
|
||||||
|
{
|
||||||
|
mMicroChunkCount--;
|
||||||
|
for (NxU32 j=i; j<mMicroChunkCount; j++)
|
||||||
|
{
|
||||||
|
mMicroChunks[j] = mMicroChunks[j+1];
|
||||||
|
}
|
||||||
|
#ifdef _DEBUG
|
||||||
|
removed = true;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef _DEBUG
|
||||||
|
assert(removed);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void * inline_malloc(size_t size)
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
void *ret = mFixedAllocators[size]->allocate(this);
|
||||||
|
Unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void inline_free(void *p,MemoryChunk *chunk) // free relative to previously located MemoryChunk
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
chunk->deallocate(p,mHeap,this);
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MemoryChunk * inline_isMicroAlloc(const void *p) // returns pointer to the chunk this memory belongs to, or null if not a micro-allocated block.
|
||||||
|
{
|
||||||
|
MemoryChunk *ret = 0;
|
||||||
|
|
||||||
|
Lock();
|
||||||
|
|
||||||
|
const NxU8 *s = (const NxU8 *)p;
|
||||||
|
|
||||||
|
if ( s >= mChunkStart && s < mChunkEnd )
|
||||||
|
{
|
||||||
|
NxU32 index = (NxU32)(s-mChunkStart)/mChunkSize;
|
||||||
|
assert(index>=0 && index < 6 );
|
||||||
|
ret = &mAlloc[index].mChunks.mChunks[0];
|
||||||
|
}
|
||||||
|
else if ( mMicroChunkCount )
|
||||||
|
{
|
||||||
|
if ( mLastMicroChunk && mLastMicroChunk->inside(s) )
|
||||||
|
{
|
||||||
|
ret = mLastMicroChunk->mChunk;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( mMicroChunkCount >= 4 )
|
||||||
|
{
|
||||||
|
ret = binarySearchMicroChunks(s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (NxU32 i=0; i<mMicroChunkCount; i++)
|
||||||
|
{
|
||||||
|
if ( mMicroChunks[i].inside(s) )
|
||||||
|
{
|
||||||
|
ret = mMicroChunks[i].mChunk;
|
||||||
|
mLastMicroChunk = &mMicroChunks[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
MicroHeap *mHeap;
|
||||||
|
NxU8 *mBaseMem;
|
||||||
|
NxU8 *mBaseMemEnd;
|
||||||
|
FixedMemory *mFixedAllocators[257];
|
||||||
|
NxU32 mChunkSize;
|
||||||
|
NxU8 *mChunkStart;
|
||||||
|
NxU8 *mChunkEnd;
|
||||||
|
|
||||||
|
NxU32 mMaxMicroChunks;
|
||||||
|
NxU32 mMicroChunkCount;
|
||||||
|
MicroChunk *mLastMicroChunk;
|
||||||
|
MicroChunk *mMicroChunks;
|
||||||
|
|
||||||
|
FixedMemory mAlloc[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MicroAllocator *createMicroAllocator(MicroHeap *heap,NxU32 chunkSize)
|
||||||
|
{
|
||||||
|
NxU32 initialSize = chunkSize*6+sizeof(MyMicroAllocator)+32;
|
||||||
|
void *baseMem = heap->micro_malloc(initialSize);
|
||||||
|
MyMicroAllocator *mc = (MyMicroAllocator *)baseMem;
|
||||||
|
new ( mc ) MyMicroAllocator(heap,baseMem,initialSize,chunkSize);
|
||||||
|
return static_cast< MicroAllocator *>(mc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void releaseMicroAllocator(MicroAllocator *m)
|
||||||
|
{
|
||||||
|
MyMicroAllocator *mc = static_cast< MyMicroAllocator *>(m);
|
||||||
|
MicroHeap *mh = mc->getMicroHeap();
|
||||||
|
mc->~MyMicroAllocator();
|
||||||
|
mh->micro_free(mc);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyHeapManager : public MicroHeap, public HeapManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyHeapManager(NxU32 defaultChunkSize)
|
||||||
|
{
|
||||||
|
mMicro = createMicroAllocator(this,defaultChunkSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MyHeapManager(void)
|
||||||
|
{
|
||||||
|
releaseMicroAllocator(mMicro);
|
||||||
|
}
|
||||||
|
|
||||||
|
// heap allocations used by the micro allocator.
|
||||||
|
virtual void * micro_malloc(size_t size)
|
||||||
|
{
|
||||||
|
return ::malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void micro_free(void *p)
|
||||||
|
{
|
||||||
|
return ::free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * micro_realloc(void *oldMem,size_t newSize)
|
||||||
|
{
|
||||||
|
return ::realloc(oldMem,newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * heap_malloc(size_t size)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if ( size <= 256 ) // micro allocator only handles allocations between 0 and 256 bytes in length.
|
||||||
|
{
|
||||||
|
ret = mMicro->malloc(size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = ::malloc(size);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void heap_free(void *p)
|
||||||
|
{
|
||||||
|
MemoryChunk *chunk = mMicro->isMicroAlloc(p);
|
||||||
|
if ( chunk )
|
||||||
|
{
|
||||||
|
mMicro->free(p,chunk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * heap_realloc(void *oldMem,size_t newSize)
|
||||||
|
{
|
||||||
|
void *ret = 0;
|
||||||
|
|
||||||
|
MemoryChunk *chunk = mMicro->isMicroAlloc(oldMem);
|
||||||
|
if ( chunk )
|
||||||
|
{
|
||||||
|
ret = heap_malloc(newSize);
|
||||||
|
NxU32 oldSize = chunk->getChunkSize();
|
||||||
|
if ( oldSize < newSize )
|
||||||
|
{
|
||||||
|
memcpy(ret,oldMem,oldSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(ret,oldMem,newSize);
|
||||||
|
}
|
||||||
|
mMicro->free(oldMem,chunk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = ::realloc(oldMem,newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void * inline_heap_malloc(size_t size)
|
||||||
|
{
|
||||||
|
return size<=256 ? ((MyMicroAllocator *)mMicro)->inline_malloc(size) : ::malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void inline_heap_free(void *p)
|
||||||
|
{
|
||||||
|
MemoryChunk *chunk = ((MyMicroAllocator *)mMicro)->inline_isMicroAlloc(p);
|
||||||
|
if ( chunk )
|
||||||
|
{
|
||||||
|
((MyMicroAllocator *)mMicro)->inline_free(p,chunk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MicroAllocator *mMicro;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
HeapManager * createHeapManager(NxU32 defaultChunkSize)
|
||||||
|
{
|
||||||
|
MyHeapManager *m = (MyHeapManager *)::malloc(sizeof(MyHeapManager));
|
||||||
|
new ( m ) MyHeapManager(defaultChunkSize);
|
||||||
|
return static_cast< HeapManager *>(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void releaseHeapManager(HeapManager *heap)
|
||||||
|
{
|
||||||
|
MyHeapManager *m = static_cast< MyHeapManager *>(heap);
|
||||||
|
m->~MyHeapManager();
|
||||||
|
free(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define TEST_SIZE 63
|
||||||
|
#define TEST_ALLOC_COUNT 8192
|
||||||
|
#define TEST_RUN 40000000
|
||||||
|
#define TEST_INLINE 1
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#pragma comment(lib,"winmm.lib")
|
||||||
|
#else
|
||||||
|
static NxU32 timeGetTime(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void performUnitTests(void)
|
||||||
|
{
|
||||||
|
void *allocs[TEST_ALLOC_COUNT];
|
||||||
|
for (NxU32 i=0; i<TEST_ALLOC_COUNT; i++)
|
||||||
|
{
|
||||||
|
allocs[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HeapManager *hm = createHeapManager(65536*32);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
NxU32 stime = timeGetTime();
|
||||||
|
srand(0);
|
||||||
|
|
||||||
|
|
||||||
|
for (NxU32 i=0; i<TEST_RUN; i++)
|
||||||
|
{
|
||||||
|
NxU32 index = rand()&(TEST_ALLOC_COUNT-1);
|
||||||
|
if ( allocs[index] )
|
||||||
|
{
|
||||||
|
#if TEST_INLINE
|
||||||
|
heap_free(hm, allocs[index] );
|
||||||
|
#else
|
||||||
|
hm->heap_free( allocs[index] );
|
||||||
|
#endif
|
||||||
|
allocs[index] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NxU32 asize = (rand()&TEST_SIZE);
|
||||||
|
if ( (rand()&127)==0) asize+=256; // one out of every 15 allocs is larger than 256 bytes.
|
||||||
|
#if TEST_INLINE
|
||||||
|
allocs[index] = heap_malloc(hm,asize);
|
||||||
|
#else
|
||||||
|
allocs[index] = hm->heap_malloc(asize);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NxU32 i=0; i<TEST_ALLOC_COUNT; i++)
|
||||||
|
{
|
||||||
|
if ( allocs[i] )
|
||||||
|
{
|
||||||
|
#if TEST_INLINE
|
||||||
|
heap_free(hm,allocs[i] );
|
||||||
|
#else
|
||||||
|
hm->heap_free(allocs[i] );
|
||||||
|
#endif
|
||||||
|
allocs[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU32 etime = timeGetTime();
|
||||||
|
printf("Micro allocation test took %d milliseconds.\r\n", etime - stime );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
NxU32 stime = timeGetTime();
|
||||||
|
srand(0);
|
||||||
|
|
||||||
|
|
||||||
|
for (NxU32 i=0; i<TEST_RUN; i++)
|
||||||
|
{
|
||||||
|
NxU32 index = rand()&(TEST_ALLOC_COUNT-1);
|
||||||
|
if ( allocs[index] )
|
||||||
|
{
|
||||||
|
::free( allocs[index] );
|
||||||
|
allocs[index] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NxU32 asize = (rand()&TEST_SIZE);
|
||||||
|
if ( (rand()&127)==0) asize+=256; // one out of every 15 allocs is larger than 256 bytes.
|
||||||
|
allocs[index] = ::malloc(asize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NxU32 i=0; i<TEST_ALLOC_COUNT; i++)
|
||||||
|
{
|
||||||
|
if ( allocs[i] )
|
||||||
|
{
|
||||||
|
::free(allocs[i] );
|
||||||
|
allocs[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NxU32 etime = timeGetTime();
|
||||||
|
printf("Standard malloc/free test took %d milliseconds.\r\n", etime - stime );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseHeapManager(hm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void * heap_malloc(HeapManager *hm,size_t size)
|
||||||
|
{
|
||||||
|
return ((MyHeapManager *)hm)->inline_heap_malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void heap_free(HeapManager *hm,void *p)
|
||||||
|
{
|
||||||
|
((MyHeapManager *)hm)->inline_heap_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void * heap_realloc(HeapManager *hm,void *oldMem,size_t newSize)
|
||||||
|
{
|
||||||
|
return hm->heap_realloc(oldMem,newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end of namespace
|
||||||
204
indra/libhacd/hacdMicroAllocator.h
Normal file
204
indra/libhacd/hacdMicroAllocator.h
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
#ifndef MICRO_ALLOCATOR_H
|
||||||
|
|
||||||
|
#define MICRO_ALLOCATOR_H
|
||||||
|
|
||||||
|
/*!
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliffscarab@gmail.com
|
||||||
|
**
|
||||||
|
** If you find this code useful or you are feeling particularily generous I would
|
||||||
|
** ask that you please go to http://www.amillionpixels.us and make a donation
|
||||||
|
** to Troy DeMolay.
|
||||||
|
**
|
||||||
|
** If you wish to contact me you can use the following methods:
|
||||||
|
**
|
||||||
|
** Skype ID: jratcliff63367
|
||||||
|
** email: jratcliffscarab@gmail.com
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** The MIT license:
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and associated documentation files (the "Software"), to deal
|
||||||
|
** in the Software without restriction, including without limitation the rights
|
||||||
|
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
** copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
** to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in all
|
||||||
|
** copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
** 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 code snippet provides a high speed micro-allocator.
|
||||||
|
//
|
||||||
|
// The concept is that you reserve an initial bank of memory for small allocations. Ideally a megabyte or two.
|
||||||
|
// The amount of memory reserved is equal to chunkSize*6
|
||||||
|
//
|
||||||
|
// All micro-allocations are split into 6 seperate pools.
|
||||||
|
// They are: 0-8 bytes
|
||||||
|
// 9-32 bytes
|
||||||
|
// 33-64 bytes
|
||||||
|
// 65-128 bytes
|
||||||
|
// 129-256 bytes
|
||||||
|
//
|
||||||
|
// On creation of the micro-allocation system you preserve a certiain amount of memory for each of these banks.
|
||||||
|
//
|
||||||
|
// The user provides a heap interface to callback for additional memory as needed.
|
||||||
|
//
|
||||||
|
// In most cases allocations are order-N and frees are order-N as well.
|
||||||
|
//
|
||||||
|
// The larger a buffer you provide, the closer to 'order-N' the allocator behaves.
|
||||||
|
//
|
||||||
|
// This kind of a micro-allocator is ideal for use with STL as it does many tiny allocations.
|
||||||
|
// All allocations are 16 byte aligned (with the exception of the 8 byte allocations, which are 8 byte aligned every other one).
|
||||||
|
//
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
typedef __int64 NxI64;
|
||||||
|
typedef signed int NxI32;
|
||||||
|
typedef signed short NxI16;
|
||||||
|
typedef signed char NxI8;
|
||||||
|
|
||||||
|
typedef unsigned __int64 NxU64;
|
||||||
|
typedef unsigned int NxU32;
|
||||||
|
typedef unsigned short NxU16;
|
||||||
|
typedef unsigned char NxU8;
|
||||||
|
|
||||||
|
typedef float NxF32;
|
||||||
|
typedef double NxF64;
|
||||||
|
|
||||||
|
#elif __gnu_linux__
|
||||||
|
typedef long long NxI64;
|
||||||
|
typedef signed int NxI32;
|
||||||
|
typedef signed short NxI16;
|
||||||
|
typedef signed char NxI8;
|
||||||
|
|
||||||
|
typedef unsigned long long NxU64;
|
||||||
|
typedef unsigned int NxU32;
|
||||||
|
typedef unsigned short NxU16;
|
||||||
|
typedef unsigned char NxU8;
|
||||||
|
|
||||||
|
typedef float NxF32;
|
||||||
|
typedef double NxF64;
|
||||||
|
|
||||||
|
#elif __APPLE__
|
||||||
|
typedef long long NxI64;
|
||||||
|
typedef signed int NxI32;
|
||||||
|
typedef signed short NxI16;
|
||||||
|
typedef signed char NxI8;
|
||||||
|
|
||||||
|
typedef unsigned long long NxU64;
|
||||||
|
typedef unsigned int NxU32;
|
||||||
|
typedef unsigned short NxU16;
|
||||||
|
typedef unsigned char NxU8;
|
||||||
|
|
||||||
|
typedef float NxF32;
|
||||||
|
typedef double NxF64;
|
||||||
|
|
||||||
|
#elif __CELLOS_LV2__
|
||||||
|
typedef long long NxI64;
|
||||||
|
typedef signed int NxI32;
|
||||||
|
typedef signed short NxI16;
|
||||||
|
typedef signed char NxI8;
|
||||||
|
|
||||||
|
typedef unsigned long long NxU64;
|
||||||
|
typedef unsigned int NxU32;
|
||||||
|
typedef unsigned short NxU16;
|
||||||
|
typedef unsigned char NxU8;
|
||||||
|
|
||||||
|
typedef float NxF32;
|
||||||
|
typedef double NxF64;
|
||||||
|
|
||||||
|
#elif _XBOX
|
||||||
|
typedef __int64 NxI64;
|
||||||
|
typedef signed int NxI32;
|
||||||
|
typedef signed short NxI16;
|
||||||
|
typedef signed char NxI8;
|
||||||
|
|
||||||
|
typedef unsigned __int64 NxU64;
|
||||||
|
typedef unsigned int NxU32;
|
||||||
|
typedef unsigned short NxU16;
|
||||||
|
typedef unsigned char NxU8;
|
||||||
|
|
||||||
|
typedef float NxF32;
|
||||||
|
typedef double NxF64;
|
||||||
|
|
||||||
|
#elif defined(__PPCGEKKO__)
|
||||||
|
typedef long long NxI64;
|
||||||
|
typedef signed int NxI32;
|
||||||
|
typedef signed short NxI16;
|
||||||
|
typedef signed char NxI8;
|
||||||
|
|
||||||
|
typedef unsigned long long NxU64;
|
||||||
|
typedef unsigned int NxU32;
|
||||||
|
typedef unsigned short NxU16;
|
||||||
|
|
||||||
|
typedef float NxF32;
|
||||||
|
typedef double NxF64;
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unknown platform!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
|
||||||
|
// user provided heap allocator
|
||||||
|
class MicroHeap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void * micro_malloc(size_t size) = 0;
|
||||||
|
virtual void micro_free(void *p) = 0;
|
||||||
|
virtual void * micro_realloc(void *oldMen,size_t newSize) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MemoryChunk;
|
||||||
|
|
||||||
|
class MicroAllocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void * malloc(size_t size) = 0;
|
||||||
|
virtual void free(void *p,MemoryChunk *chunk) = 0; // free relative to previously located MemoryChunk
|
||||||
|
virtual MemoryChunk * isMicroAlloc(const void *p) = 0; // returns pointer to the chunk this memory belongs to, or null if not a micro-allocated block.
|
||||||
|
virtual NxU32 getChunkSize(MemoryChunk *chunk) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
MicroAllocator *createMicroAllocator(MicroHeap *heap,NxU32 chunkSize=32768); // initial chunk size 32k per block.
|
||||||
|
void releaseMicroAllocator(MicroAllocator *m);
|
||||||
|
|
||||||
|
class HeapManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void * heap_malloc(size_t size) = 0;
|
||||||
|
virtual void heap_free(void *p) = 0;
|
||||||
|
virtual void * heap_realloc(void *oldMem,size_t newSize) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// creates a heap manager that uses micro-allocations for all allocations < 256 bytes and standard malloc/free for anything larger.
|
||||||
|
HeapManager * createHeapManager(NxU32 defaultChunkSize=32768);
|
||||||
|
void releaseHeapManager(HeapManager *heap);
|
||||||
|
|
||||||
|
// about 10% faster than using the virtual interface, inlines the functions as much as possible.
|
||||||
|
void * heap_malloc(HeapManager *hm,size_t size);
|
||||||
|
void heap_free(HeapManager *hm,void *p);
|
||||||
|
void * heap_realloc(HeapManager *hm,void *oldMem,size_t newSize);
|
||||||
|
|
||||||
|
void performUnitTests(void);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}; // end of namespace
|
||||||
|
|
||||||
|
#endif
|
||||||
280
indra/libhacd/hacdRaycastMesh.cpp
Normal file
280
indra/libhacd/hacdRaycastMesh.cpp
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#include "hacdRaycastMesh.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits>
|
||||||
|
#include "hacdManifoldMesh.h"
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
bool BBox::Raycast(const Vec3<Float> & origin, const Vec3<Float> & dir, Float & distMin) const
|
||||||
|
{
|
||||||
|
Vec3<Float> d = m_max - m_min;
|
||||||
|
Float r2 = 0.25 * (d.X()*d.X()+d.Y()*d.Y()+d.Z()*d.Z());
|
||||||
|
Vec3<Float> c = 0.5 * m_max + 0.5 * m_min;
|
||||||
|
Vec3<Float> u = (c-origin);
|
||||||
|
Vec3<Float> a = u - (u * dir) * dir;
|
||||||
|
Float dist2 = (a.X()*a.X()+a.Y()*a.Y()+a.Z()*a.Z());
|
||||||
|
distMin = (u.X()*u.X()+u.Y()*u.Y()+u.Z()*u.Z());
|
||||||
|
if ( distMin > r2 ) // origin outside the sphere of center c and radius r
|
||||||
|
{
|
||||||
|
distMin = sqrt(distMin) - sqrt(r2); // the distance to any point inside the sphere is higher than |origin - c| - r
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
distMin = 0.0;
|
||||||
|
}
|
||||||
|
if (dist2 > r2) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void RMNode::ComputeBB()
|
||||||
|
{
|
||||||
|
if (m_triIDs.Size() == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vec3<long> * const triangles = m_rm->m_triangles;
|
||||||
|
Vec3<Float> * const vertices = m_rm->m_vertices;
|
||||||
|
const Float minFloat = std::numeric_limits<Float>::min();
|
||||||
|
const Float maxFloat = std::numeric_limits<Float>::max();
|
||||||
|
m_bBox.m_max = Vec3<Float>(minFloat, minFloat, minFloat);
|
||||||
|
m_bBox.m_min = Vec3<Float>(maxFloat, maxFloat, maxFloat);
|
||||||
|
Float x, y, z;
|
||||||
|
long v, f;
|
||||||
|
for(size_t id = 0; id < m_triIDs.Size(); ++id)
|
||||||
|
{
|
||||||
|
f = m_triIDs[id];
|
||||||
|
for(size_t k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
v = triangles[f][k];
|
||||||
|
x = vertices[v].X();
|
||||||
|
y = vertices[v].Y();
|
||||||
|
z = vertices[v].Z();
|
||||||
|
if ( x < m_bBox.m_min.X()) m_bBox.m_min.X() = x;
|
||||||
|
if ( x > m_bBox.m_max.X()) m_bBox.m_max.X() = x;
|
||||||
|
if ( y < m_bBox.m_min.Y()) m_bBox.m_min.Y() = y;
|
||||||
|
if ( y > m_bBox.m_max.Y()) m_bBox.m_max.Y() = y;
|
||||||
|
if ( z < m_bBox.m_min.Z()) m_bBox.m_min.Z() = z;
|
||||||
|
if ( z > m_bBox.m_max.Z()) m_bBox.m_max.Z() = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void RaycastMesh::ComputeBB()
|
||||||
|
{
|
||||||
|
if (m_nVertices == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_bBox.m_min = m_vertices[0];
|
||||||
|
m_bBox.m_max = m_vertices[0];
|
||||||
|
Float x, y, z;
|
||||||
|
for (size_t v = 1; v < m_nVertices ; v++)
|
||||||
|
{
|
||||||
|
x = m_vertices[v].X();
|
||||||
|
y = m_vertices[v].Y();
|
||||||
|
z = m_vertices[v].Z();
|
||||||
|
if ( x < m_bBox.m_min.X()) m_bBox.m_min.X() = x;
|
||||||
|
else if ( x > m_bBox.m_max.X()) m_bBox.m_max.X() = x;
|
||||||
|
if ( y < m_bBox.m_min.Y()) m_bBox.m_min.Y() = y;
|
||||||
|
else if ( y > m_bBox.m_max.Y()) m_bBox.m_max.Y() = y;
|
||||||
|
if ( z < m_bBox.m_min.Z()) m_bBox.m_min.Z() = z;
|
||||||
|
else if ( z > m_bBox.m_max.Z()) m_bBox.m_max.Z() = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void RaycastMesh::Initialize(size_t nVertices, size_t nTriangles,
|
||||||
|
Vec3<Float> * vertices, Vec3<long> * triangles,
|
||||||
|
size_t maxDepth, size_t minLeafSize, Float minAxisSize)
|
||||||
|
{
|
||||||
|
m_triangles = triangles;
|
||||||
|
m_vertices = vertices;
|
||||||
|
m_nVertices = nVertices;
|
||||||
|
m_nTriangles = nTriangles;
|
||||||
|
delete [] m_nodes;
|
||||||
|
m_nNodes = 0;
|
||||||
|
m_nMaxNodes = 0;
|
||||||
|
for(size_t k = 0; k < maxDepth; k++)
|
||||||
|
{
|
||||||
|
m_nMaxNodes += (1 << maxDepth);
|
||||||
|
}
|
||||||
|
m_nodes = new RMNode[m_nMaxNodes];
|
||||||
|
RMNode & root = m_nodes[AddNode()];
|
||||||
|
root.m_triIDs.Resize(nTriangles);
|
||||||
|
for(size_t t = 0; t < m_nTriangles; ++t) root.m_triIDs.PushBack(t);
|
||||||
|
root.m_rm = this;
|
||||||
|
root.m_id = 0;
|
||||||
|
root.Create(0, maxDepth, minLeafSize, minAxisSize);
|
||||||
|
}
|
||||||
|
RaycastMesh::RaycastMesh(void)
|
||||||
|
{
|
||||||
|
m_triangles = 0;
|
||||||
|
m_vertices = 0;
|
||||||
|
m_nVertices = 0;
|
||||||
|
m_nTriangles = 0;
|
||||||
|
m_nodes = 0;
|
||||||
|
m_nNodes = 0;
|
||||||
|
m_nMaxNodes = 0;
|
||||||
|
}
|
||||||
|
RaycastMesh::~RaycastMesh(void)
|
||||||
|
{
|
||||||
|
delete [] m_nodes;
|
||||||
|
}
|
||||||
|
void RMNode::Create(size_t depth, size_t maxDepth, size_t minLeafSize, Float minAxisSize)
|
||||||
|
{
|
||||||
|
ComputeBB();
|
||||||
|
Vec3<Float> d = m_bBox.m_max - m_bBox.m_min;
|
||||||
|
Float maxDiff = std::max<Float>(d.X(), std::max<Float>(d.Y(), d.Z()));
|
||||||
|
RMSplitAxis split;
|
||||||
|
if (d.X() == maxDiff) split = RMSplitAxis_X;
|
||||||
|
else if (d.Y() == maxDiff) split = RMSplitAxis_Y;
|
||||||
|
else split = RMSplitAxis_Z;
|
||||||
|
|
||||||
|
if (depth == maxDepth || minLeafSize >= m_triIDs.Size() || maxDiff < minAxisSize)
|
||||||
|
{
|
||||||
|
m_leaf = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_idLeft = m_rm->AddNode();
|
||||||
|
m_idRight = m_rm->AddNode();
|
||||||
|
RMNode & leftNode = m_rm->m_nodes[m_idLeft];
|
||||||
|
RMNode & rightNode = m_rm->m_nodes[m_idRight];
|
||||||
|
leftNode.m_id = m_idLeft;
|
||||||
|
rightNode.m_id = m_idRight;
|
||||||
|
leftNode.m_bBox = m_bBox;
|
||||||
|
rightNode.m_bBox = m_bBox;
|
||||||
|
leftNode.m_rm = m_rm;
|
||||||
|
rightNode.m_rm = m_rm;
|
||||||
|
|
||||||
|
if ( split == RMSplitAxis_X)
|
||||||
|
{
|
||||||
|
leftNode.m_bBox.m_max.X() = leftNode.m_bBox.m_max.X() - d.X() * 0.5;
|
||||||
|
rightNode.m_bBox.m_min.X() = leftNode.m_bBox.m_max.X();
|
||||||
|
}
|
||||||
|
else if ( split == RMSplitAxis_Y)
|
||||||
|
{
|
||||||
|
leftNode.m_bBox.m_max.Y() = leftNode.m_bBox.m_max.Y() - d.Y() * 0.5;
|
||||||
|
rightNode.m_bBox.m_min.Y() = leftNode.m_bBox.m_max.Y();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leftNode.m_bBox.m_max.Z() = leftNode.m_bBox.m_max.Z() - d.Z() * 0.5;
|
||||||
|
rightNode.m_bBox.m_min.Z() = leftNode.m_bBox.m_max.Z();
|
||||||
|
}
|
||||||
|
long f;
|
||||||
|
long pts[3];
|
||||||
|
long v;
|
||||||
|
Vec3<long> * const triangles = m_rm->m_triangles;
|
||||||
|
Vec3<Float> * const vertices = m_rm->m_vertices;
|
||||||
|
leftNode.m_triIDs.Resize(m_triIDs.Size());
|
||||||
|
rightNode.m_triIDs.Resize(m_triIDs.Size());
|
||||||
|
bool found;
|
||||||
|
for(size_t id = 0; id < m_triIDs.Size(); ++id)
|
||||||
|
{
|
||||||
|
f = m_triIDs[id];
|
||||||
|
pts[0] = triangles[f].X();
|
||||||
|
pts[1] = triangles[f].Y();
|
||||||
|
pts[2] = triangles[f].Z();
|
||||||
|
|
||||||
|
found = false;
|
||||||
|
for (int k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
v = pts[k];
|
||||||
|
if ( vertices[v].X() <= leftNode.m_bBox.m_max.X() &&
|
||||||
|
vertices[v].X() >= leftNode.m_bBox.m_min.X() &&
|
||||||
|
vertices[v].Y() <= leftNode.m_bBox.m_max.Y() &&
|
||||||
|
vertices[v].Y() >= leftNode.m_bBox.m_min.Y() &&
|
||||||
|
vertices[v].Z() <= leftNode.m_bBox.m_max.Z() &&
|
||||||
|
vertices[v].Z() >= leftNode.m_bBox.m_min.Z() )
|
||||||
|
{
|
||||||
|
leftNode.m_triIDs.PushBack(f);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
v = pts[k];
|
||||||
|
if ( vertices[v].X() <= rightNode.m_bBox.m_max.X() &&
|
||||||
|
vertices[v].X() >= rightNode.m_bBox.m_min.X() &&
|
||||||
|
vertices[v].Y() <= rightNode.m_bBox.m_max.Y() &&
|
||||||
|
vertices[v].Y() >= rightNode.m_bBox.m_min.Y() &&
|
||||||
|
vertices[v].Z() <= rightNode.m_bBox.m_max.Z() &&
|
||||||
|
vertices[v].Z() >= rightNode.m_bBox.m_min.Z() )
|
||||||
|
{
|
||||||
|
rightNode.m_triIDs.PushBack(f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rightNode.Create(depth+1, maxDepth, minLeafSize, minAxisSize);
|
||||||
|
leftNode.Create(depth+1, maxDepth, minLeafSize, minAxisSize);
|
||||||
|
m_triIDs.Clear();
|
||||||
|
}
|
||||||
|
bool RaycastMesh::Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const
|
||||||
|
{
|
||||||
|
distance = std::numeric_limits<Float>::max();
|
||||||
|
if (m_nNodes == 0) return false;
|
||||||
|
return m_nodes[0].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
|
||||||
|
}
|
||||||
|
bool RMNode::Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const
|
||||||
|
{
|
||||||
|
Float distToSphere;
|
||||||
|
if (m_bBox.Raycast(from, dir, distToSphere) && (distToSphere < distance))
|
||||||
|
{
|
||||||
|
if (m_leaf)
|
||||||
|
{
|
||||||
|
long f, i1, j1, k1;
|
||||||
|
Vec3<long> * const triangles = m_rm->m_triangles;
|
||||||
|
Vec3<Float> * const vertices = m_rm->m_vertices;
|
||||||
|
Vec3<Real> u1, v1, normal1;
|
||||||
|
double dist = 0.0;
|
||||||
|
long nhit = 0;
|
||||||
|
bool ret = false;
|
||||||
|
for(size_t id = 0; id < m_triIDs.Size(); ++id)
|
||||||
|
{
|
||||||
|
f = m_triIDs[id];
|
||||||
|
i1 = triangles[f].X();
|
||||||
|
j1 = triangles[f].Y();
|
||||||
|
k1 = triangles[f].Z();
|
||||||
|
u1 = vertices[j1] - vertices[i1];
|
||||||
|
v1 = vertices[k1] - vertices[i1];
|
||||||
|
normal1 = (u1 ^ v1);
|
||||||
|
if (dir * normal1 > 0.0)
|
||||||
|
{
|
||||||
|
nhit = IntersectRayTriangle(from, dir, vertices[i1], vertices[j1], vertices[k1], dist);
|
||||||
|
if (nhit==1 && distance>dist)
|
||||||
|
{
|
||||||
|
normal1.Normalize();
|
||||||
|
hitNormal = normal1;
|
||||||
|
hitPoint = from + dist * dir;
|
||||||
|
distance = dist;
|
||||||
|
triID = f;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool ret1 = false;
|
||||||
|
bool ret2 = false;
|
||||||
|
if (m_idRight >= 0) ret1 = m_rm->m_nodes[m_idRight].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
|
||||||
|
if (m_idLeft >= 0) ret2 = m_rm->m_nodes[m_idLeft].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
|
||||||
|
return ret1 || ret2;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
97
indra/libhacd/hacdRaycastMesh.h
Normal file
97
indra/libhacd/hacdRaycastMesh.h
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#ifndef RAYCAST_MESH_H
|
||||||
|
#define RAYCAST_MESH_H
|
||||||
|
#include "hacdSArray.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include "hacdVector.h"
|
||||||
|
#include "hacdSArray.h"
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
typedef double Float;
|
||||||
|
class RaycastMesh;
|
||||||
|
class RMNode;
|
||||||
|
class BBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Raycast(const Vec3<Float> & origin, const Vec3<Float> & dir, Float & distance) const;
|
||||||
|
BBox(void){}
|
||||||
|
~BBox(void){}
|
||||||
|
private:
|
||||||
|
Vec3<Float> m_min;
|
||||||
|
Vec3<Float> m_max;
|
||||||
|
friend class RMNode;
|
||||||
|
friend class RaycastMesh;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RMSplitAxis
|
||||||
|
{
|
||||||
|
RMSplitAxis_X,
|
||||||
|
RMSplitAxis_Y,
|
||||||
|
RMSplitAxis_Z
|
||||||
|
};
|
||||||
|
class RMNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void ComputeBB();
|
||||||
|
bool Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const;
|
||||||
|
void Create(size_t depth, size_t maxDepth, size_t minLeafSize, Float minAxisSize);
|
||||||
|
~RMNode(void){}
|
||||||
|
RMNode(void)
|
||||||
|
{
|
||||||
|
m_idRight = m_idLeft = m_id = -1;
|
||||||
|
m_rm = 0;
|
||||||
|
m_leaf = false;
|
||||||
|
}
|
||||||
|
long m_id;
|
||||||
|
long m_idLeft;
|
||||||
|
long m_idRight;
|
||||||
|
BBox m_bBox;
|
||||||
|
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_triIDs;
|
||||||
|
RaycastMesh * m_rm;
|
||||||
|
bool m_leaf;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RaycastMesh
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
size_t GetNNodes() const { return m_nNodes;}
|
||||||
|
size_t AddNode() { m_nNodes++; return m_nNodes-1; }
|
||||||
|
void ComputeBB();
|
||||||
|
bool Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const;
|
||||||
|
void Initialize(size_t nVertices, size_t nTriangles,
|
||||||
|
Vec3<Float> * vertices, Vec3<long> * triangles,
|
||||||
|
size_t maxDepth=15, size_t minLeafSize = 4, Float minAxisSize = 2.0);
|
||||||
|
RaycastMesh(void);
|
||||||
|
~RaycastMesh(void);
|
||||||
|
private :
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vec3<long> * m_triangles;
|
||||||
|
Vec3<Float> * m_vertices;
|
||||||
|
size_t m_nVertices;
|
||||||
|
size_t m_nTriangles;
|
||||||
|
RMNode * m_nodes;
|
||||||
|
BBox m_bBox;
|
||||||
|
size_t m_nNodes;
|
||||||
|
size_t m_nMaxNodes;
|
||||||
|
friend class RMNode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
154
indra/libhacd/hacdSArray.h
Normal file
154
indra/libhacd/hacdSArray.h
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_SARRAY_H
|
||||||
|
#define HACD_SARRAY_H
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define SARRAY_DEFAULT_MIN_SIZE 16
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
//! SArray.
|
||||||
|
template < typename T, size_t N > class SArray
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T & operator[](size_t i)
|
||||||
|
{
|
||||||
|
T * const data = Data();
|
||||||
|
return data[i];
|
||||||
|
}
|
||||||
|
const T & operator[](size_t i) const
|
||||||
|
{
|
||||||
|
const T * const data = Data();
|
||||||
|
return data[i];
|
||||||
|
}
|
||||||
|
size_t Size() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
T * const Data()
|
||||||
|
{
|
||||||
|
return (m_maxSize == N)? m_data0 : m_data;
|
||||||
|
}
|
||||||
|
const T * const Data() const
|
||||||
|
{
|
||||||
|
return (m_maxSize == N)? m_data0 : m_data;
|
||||||
|
}
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
m_size = 0;
|
||||||
|
delete [] m_data;
|
||||||
|
m_data = 0;
|
||||||
|
m_maxSize = N;
|
||||||
|
}
|
||||||
|
void PopBack()
|
||||||
|
{
|
||||||
|
--m_size;
|
||||||
|
}
|
||||||
|
void Resize(size_t size)
|
||||||
|
{
|
||||||
|
if (size > m_maxSize)
|
||||||
|
{
|
||||||
|
T * temp = new T[size];
|
||||||
|
memcpy(temp, Data(), m_size*sizeof(T));
|
||||||
|
delete [] m_data;
|
||||||
|
m_data = temp;
|
||||||
|
m_maxSize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void PushBack(const T & value)
|
||||||
|
{
|
||||||
|
if (m_size==m_maxSize)
|
||||||
|
{
|
||||||
|
size_t maxSize = (m_maxSize << 1);
|
||||||
|
T * temp = new T[maxSize];
|
||||||
|
memcpy(temp, Data(), m_maxSize*sizeof(T));
|
||||||
|
delete [] m_data;
|
||||||
|
m_data = temp;
|
||||||
|
m_maxSize = maxSize;
|
||||||
|
}
|
||||||
|
T * const data = Data();
|
||||||
|
data[m_size++] = value;
|
||||||
|
}
|
||||||
|
bool Find(const T & value, size_t & pos)
|
||||||
|
{
|
||||||
|
T * const data = Data();
|
||||||
|
for(pos = 0; pos < m_size; ++pos)
|
||||||
|
if (value == data[pos]) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool Insert(const T & value)
|
||||||
|
{
|
||||||
|
size_t pos;
|
||||||
|
if (Find(value, pos)) return false;
|
||||||
|
PushBack(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Erase(const T & value)
|
||||||
|
{
|
||||||
|
size_t pos;
|
||||||
|
T * const data = Data();
|
||||||
|
if (Find(value, pos))
|
||||||
|
{
|
||||||
|
for(size_t j = pos+1; j < m_size; ++j)
|
||||||
|
data[j-1] = data[j];
|
||||||
|
--m_size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void operator=(const SArray & rhs)
|
||||||
|
{
|
||||||
|
if (m_maxSize < rhs.m_size)
|
||||||
|
{
|
||||||
|
delete [] m_data;
|
||||||
|
m_maxSize = rhs.m_maxSize;
|
||||||
|
m_data = new T[m_maxSize];
|
||||||
|
}
|
||||||
|
m_size = rhs.m_size;
|
||||||
|
memcpy(Data(), rhs.Data(), m_size*sizeof(T));
|
||||||
|
}
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
m_data = 0;
|
||||||
|
m_size = 0;
|
||||||
|
m_maxSize = N;
|
||||||
|
}
|
||||||
|
SArray(const SArray & rhs)
|
||||||
|
{
|
||||||
|
m_data = 0;
|
||||||
|
m_size = 0;
|
||||||
|
m_maxSize = N;
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
SArray()
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
~SArray()
|
||||||
|
{
|
||||||
|
delete [] m_data;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
T m_data0[N];
|
||||||
|
T * m_data;
|
||||||
|
size_t m_size;
|
||||||
|
size_t m_maxSize;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
69
indra/libhacd/hacdVector.h
Normal file
69
indra/libhacd/hacdVector.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_VECTOR_H
|
||||||
|
#define HACD_VECTOR_H
|
||||||
|
#include <math.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include "hacdVersion.h"
|
||||||
|
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
typedef double Real;
|
||||||
|
//! Vector dim 3.
|
||||||
|
template < typename T > class Vec3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T & operator[](size_t i) { return m_data[i];}
|
||||||
|
const T & operator[](size_t i) const { return m_data[i];}
|
||||||
|
T & X();
|
||||||
|
T & Y();
|
||||||
|
T & Z();
|
||||||
|
const T & X() const;
|
||||||
|
const T & Y() const;
|
||||||
|
const T & Z() const;
|
||||||
|
void Normalize();
|
||||||
|
T GetNorm() const;
|
||||||
|
void operator= (const Vec3 & rhs);
|
||||||
|
void operator+=(const Vec3 & rhs);
|
||||||
|
void operator-=(const Vec3 & rhs);
|
||||||
|
void operator-=(T a);
|
||||||
|
void operator+=(T a);
|
||||||
|
void operator/=(T a);
|
||||||
|
void operator*=(T a);
|
||||||
|
Vec3 operator^ (const Vec3 & rhs) const;
|
||||||
|
T operator* (const Vec3 & rhs) const;
|
||||||
|
Vec3 operator+ (const Vec3 & rhs) const;
|
||||||
|
Vec3 operator- (const Vec3 & rhs) const;
|
||||||
|
Vec3 operator- () const;
|
||||||
|
Vec3 operator* (T rhs) const;
|
||||||
|
Vec3 operator/ (T rhs) const;
|
||||||
|
Vec3();
|
||||||
|
Vec3(T a);
|
||||||
|
Vec3(T x, T y, T z);
|
||||||
|
Vec3(const Vec3 & rhs);
|
||||||
|
/*virtual*/ ~Vec3(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
T m_data[3];
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
const bool Colinear(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c);
|
||||||
|
template<typename T>
|
||||||
|
const T Volume(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c, const Vec3<T> & d);
|
||||||
|
|
||||||
|
}
|
||||||
|
#include "hacdVector.inl" // template implementation
|
||||||
|
#endif
|
||||||
178
indra/libhacd/hacdVector.inl
Normal file
178
indra/libhacd/hacdVector.inl
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef HACD_VECTOR_INL
|
||||||
|
#define HACD_VECTOR_INL
|
||||||
|
namespace HACD
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T> operator*(T lhs, const Vec3<T> & rhs)
|
||||||
|
{
|
||||||
|
return Vec3<T>(lhs * rhs.X(), lhs * rhs.Y(), lhs * rhs.Z());
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline T & Vec3<T>::X()
|
||||||
|
{
|
||||||
|
return m_data[0];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline T & Vec3<T>::Y()
|
||||||
|
{
|
||||||
|
return m_data[1];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline T & Vec3<T>::Z()
|
||||||
|
{
|
||||||
|
return m_data[2];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline const T & Vec3<T>::X() const
|
||||||
|
{
|
||||||
|
return m_data[0];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline const T & Vec3<T>::Y() const
|
||||||
|
{
|
||||||
|
return m_data[1];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline const T & Vec3<T>::Z() const
|
||||||
|
{
|
||||||
|
return m_data[2];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::Normalize()
|
||||||
|
{
|
||||||
|
T n = sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]);
|
||||||
|
if (n != 0.0) (*this) /= n;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline T Vec3<T>::GetNorm() const
|
||||||
|
{
|
||||||
|
return sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::operator= (const Vec3 & rhs)
|
||||||
|
{
|
||||||
|
this->m_data[0] = rhs.m_data[0];
|
||||||
|
this->m_data[1] = rhs.m_data[1];
|
||||||
|
this->m_data[2] = rhs.m_data[2];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::operator+=(const Vec3 & rhs)
|
||||||
|
{
|
||||||
|
this->m_data[0] += rhs.m_data[0];
|
||||||
|
this->m_data[1] += rhs.m_data[1];
|
||||||
|
this->m_data[2] += rhs.m_data[2];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::operator-=(const Vec3 & rhs)
|
||||||
|
{
|
||||||
|
this->m_data[0] -= rhs.m_data[0];
|
||||||
|
this->m_data[1] -= rhs.m_data[1];
|
||||||
|
this->m_data[2] -= rhs.m_data[2];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::operator-=(T a)
|
||||||
|
{
|
||||||
|
this->m_data[0] -= a;
|
||||||
|
this->m_data[1] -= a;
|
||||||
|
this->m_data[2] -= a;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::operator+=(T a)
|
||||||
|
{
|
||||||
|
this->m_data[0] += a;
|
||||||
|
this->m_data[1] += a;
|
||||||
|
this->m_data[2] += a;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::operator/=(T a)
|
||||||
|
{
|
||||||
|
this->m_data[0] /= a;
|
||||||
|
this->m_data[1] /= a;
|
||||||
|
this->m_data[2] /= a;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline void Vec3<T>::operator*=(T a)
|
||||||
|
{
|
||||||
|
this->m_data[0] *= a;
|
||||||
|
this->m_data[1] *= a;
|
||||||
|
this->m_data[2] *= a;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T> Vec3<T>::operator^ (const Vec3<T> & rhs) const
|
||||||
|
{
|
||||||
|
return Vec3<T>(m_data[1] * rhs.m_data[2] - m_data[2] * rhs.m_data[1],
|
||||||
|
m_data[2] * rhs.m_data[0] - m_data[0] * rhs.m_data[2],
|
||||||
|
m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0]);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline T Vec3<T>::operator*(const Vec3<T> & rhs) const
|
||||||
|
{
|
||||||
|
return (m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1] + m_data[2] * rhs.m_data[2]);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T> Vec3<T>::operator+(const Vec3<T> & rhs) const
|
||||||
|
{
|
||||||
|
return Vec3<T>(m_data[0] + rhs.m_data[0],m_data[1] + rhs.m_data[1],m_data[2] + rhs.m_data[2]);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T> Vec3<T>::operator-(const Vec3<T> & rhs) const
|
||||||
|
{
|
||||||
|
return Vec3<T>(m_data[0] - rhs.m_data[0],m_data[1] - rhs.m_data[1],m_data[2] - rhs.m_data[2]) ;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T> Vec3<T>::operator-() const
|
||||||
|
{
|
||||||
|
return Vec3<T>(-m_data[0],-m_data[1],-m_data[2]) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T> Vec3<T>::operator*(T rhs) const
|
||||||
|
{
|
||||||
|
return Vec3<T>(rhs * this->m_data[0], rhs * this->m_data[1], rhs * this->m_data[2]);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T> Vec3<T>::operator/ (T rhs) const
|
||||||
|
{
|
||||||
|
return Vec3<T>(m_data[0] / rhs, m_data[1] / rhs, m_data[2] / rhs);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T>::Vec3(T a)
|
||||||
|
{
|
||||||
|
m_data[0] = m_data[1] = m_data[2] = a;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T>::Vec3(T x, T y, T z)
|
||||||
|
{
|
||||||
|
m_data[0] = x;
|
||||||
|
m_data[1] = y;
|
||||||
|
m_data[2] = z;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T>::Vec3(const Vec3 & rhs)
|
||||||
|
{
|
||||||
|
m_data[0] = rhs.m_data[0];
|
||||||
|
m_data[1] = rhs.m_data[1];
|
||||||
|
m_data[2] = rhs.m_data[2];
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T>::~Vec3(void){};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline Vec3<T>::Vec3() {}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline const bool Colinear(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c)
|
||||||
|
{
|
||||||
|
return ((c.Z() - a.Z()) * (b.Y() - a.Y()) - (b.Z() - a.Z()) * (c.Y() - a.Y()) == 0.0 /*EPS*/) &&
|
||||||
|
((b.Z() - a.Z()) * (c.X() - a.X()) - (b.X() - a.X()) * (c.Z() - a.Z()) == 0.0 /*EPS*/) &&
|
||||||
|
((b.X() - a.X()) * (c.Y() - a.Y()) - (b.Y() - a.Y()) * (c.X() - a.X()) == 0.0 /*EPS*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline const T Volume(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c, const Vec3<T> & d)
|
||||||
|
{
|
||||||
|
return (a-d) * ((b-d) ^ (c-d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //HACD_VECTOR_INL
|
||||||
20
indra/libhacd/hacdVersion.h
Normal file
20
indra/libhacd/hacdVersion.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. 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.
|
||||||
|
|
||||||
|
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
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 HOLDER 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.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef HACD_VERSION_H
|
||||||
|
#define HACD_VERSION_H
|
||||||
|
#define HACD_VERSION_MAJOR 0
|
||||||
|
#define HACD_VERSION_MINOR 0
|
||||||
|
#endif
|
||||||
9
indra/libndhacd/CMakeLists.txt
Normal file
9
indra/libndhacd/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
project(libndhacd)
|
||||||
|
|
||||||
|
include_directories(${LIBS_OPEN_DIR}/libhacd)
|
||||||
|
|
||||||
|
set (SOURCE_FILES LLConvexDecomposition.cpp nd_hacdConvexDecomposition.cpp nd_hacdStructs.cpp nd_hacdUtils.cpp nd_EnterExitTracer.cpp nd_StructTracer.cpp )
|
||||||
|
file(GLOB HEADER_FILES *.h)
|
||||||
|
|
||||||
|
add_library( nd_hacdConvexDecomposition STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||||
|
|
||||||
80
indra/libndhacd/LLConvexDecomposition.cpp
Normal file
80
indra/libndhacd/LLConvexDecomposition.cpp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* @file LLConvexDecomposition.cpp
|
||||||
|
* @author falcon@lindenlab.com
|
||||||
|
* @brief A stub implementation of LLConvexDecomposition interface
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(_WINDOWS)
|
||||||
|
# include "windowsincludes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nd_hacdConvexDecomposition.h"
|
||||||
|
|
||||||
|
#include "LLConvexDecomposition.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*static */bool LLConvexDecomposition::s_isInitialized = false;
|
||||||
|
|
||||||
|
/*static*/LLConvexDecomposition* LLConvexDecomposition::getInstance()
|
||||||
|
{
|
||||||
|
if ( !s_isInitialized )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nd_hacdConvexDecomposition::getInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static */LLCDResult LLConvexDecomposition::initSystem()
|
||||||
|
{
|
||||||
|
LLCDResult result = nd_hacdConvexDecomposition::initSystem();
|
||||||
|
if ( result == LLCD_OK )
|
||||||
|
{
|
||||||
|
s_isInitialized = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static */LLCDResult LLConvexDecomposition::initThread()
|
||||||
|
{
|
||||||
|
return nd_hacdConvexDecomposition::initThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static */LLCDResult LLConvexDecomposition::quitThread()
|
||||||
|
{
|
||||||
|
return nd_hacdConvexDecomposition::quitThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static */LLCDResult LLConvexDecomposition::quitSystem()
|
||||||
|
{
|
||||||
|
return nd_hacdConvexDecomposition::quitSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
231
indra/libndhacd/LLConvexDecomposition.h
Normal file
231
indra/libndhacd/LLConvexDecomposition.h
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
/**
|
||||||
|
* @file LLConvexDecomposition.cpp
|
||||||
|
* @brief LLConvexDecomposition interface definition
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2011, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LL_CONVEX_DECOMPOSITION
|
||||||
|
#define LL_CONVEX_DECOMPOSITION
|
||||||
|
|
||||||
|
typedef int bool32;
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
#define LLCD_CALL __cdecl
|
||||||
|
#else
|
||||||
|
#define LLCD_CALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct LLCDParam
|
||||||
|
{
|
||||||
|
enum LLCDParamType
|
||||||
|
{
|
||||||
|
LLCD_INVALID = 0,
|
||||||
|
LLCD_INTEGER,
|
||||||
|
LLCD_FLOAT,
|
||||||
|
LLCD_BOOLEAN,
|
||||||
|
LLCD_ENUM
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LLCDEnumItem
|
||||||
|
{
|
||||||
|
const char* mName;
|
||||||
|
int mValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
union LLCDValue
|
||||||
|
{
|
||||||
|
float mFloat;
|
||||||
|
int mIntOrEnumValue;
|
||||||
|
bool32 mBool;
|
||||||
|
};
|
||||||
|
|
||||||
|
union LLCDParamDetails
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
LLCDValue mLow;
|
||||||
|
LLCDValue mHigh;
|
||||||
|
LLCDValue mDelta;
|
||||||
|
} mRange;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int mNumEnums;
|
||||||
|
LLCDEnumItem* mEnumsArray;
|
||||||
|
} mEnumValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* mName;
|
||||||
|
const char* mDescription;
|
||||||
|
LLCDParamType mType;
|
||||||
|
LLCDParamDetails mDetails;
|
||||||
|
LLCDValue mDefault;
|
||||||
|
int mStage;
|
||||||
|
|
||||||
|
// WARNING: Only the LLConvexDecomposition implementation
|
||||||
|
// should change this value
|
||||||
|
int mReserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LLCDStageData
|
||||||
|
{
|
||||||
|
const char* mName;
|
||||||
|
const char* mDescription;
|
||||||
|
bool32 mSupportsCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LLCDMeshData
|
||||||
|
{
|
||||||
|
enum IndexType
|
||||||
|
{
|
||||||
|
INT_16,
|
||||||
|
INT_32
|
||||||
|
};
|
||||||
|
|
||||||
|
const float* mVertexBase;
|
||||||
|
int mVertexStrideBytes;
|
||||||
|
int mNumVertices;
|
||||||
|
const void* mIndexBase;
|
||||||
|
IndexType mIndexType;
|
||||||
|
int mIndexStrideBytes;
|
||||||
|
int mNumTriangles;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LLCDHull
|
||||||
|
{
|
||||||
|
const float* mVertexBase;
|
||||||
|
int mVertexStrideBytes;
|
||||||
|
int mNumVertices;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LLCDResult
|
||||||
|
{
|
||||||
|
LLCD_OK = 0,
|
||||||
|
LLCD_UNKOWN_ERROR,
|
||||||
|
LLCD_NULL_PTR,
|
||||||
|
LLCD_INVALID_STAGE,
|
||||||
|
LLCD_UNKNOWN_PARAM,
|
||||||
|
LLCD_BAD_VALUE,
|
||||||
|
LLCD_REQUEST_OUT_OF_RANGE,
|
||||||
|
LLCD_INVALID_MESH_DATA,
|
||||||
|
LLCD_INVALID_HULL_DATA,
|
||||||
|
LLCD_STAGE_NOT_READY,
|
||||||
|
LLCD_INVALID_THREAD,
|
||||||
|
LLCD_NOT_IMPLEMENTED
|
||||||
|
};
|
||||||
|
|
||||||
|
// This callback will receive a string describing the current subtask being performed
|
||||||
|
// as well as a pair of numbers indicating progress. (The values should not be interpreted
|
||||||
|
// as a completion percentage as 'current' may be greater than 'final'.)
|
||||||
|
// If the callback returns zero, the decomposition will be terminated
|
||||||
|
typedef int (LLCD_CALL *llcdCallbackFunc)(const char* description, int current, int final);
|
||||||
|
|
||||||
|
class LLConvexDecomposition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Obtain a pointer to the actual implementation
|
||||||
|
static LLConvexDecomposition* getInstance();
|
||||||
|
|
||||||
|
static LLCDResult initSystem();
|
||||||
|
static LLCDResult initThread();
|
||||||
|
static LLCDResult quitThread();
|
||||||
|
static LLCDResult quitSystem();
|
||||||
|
|
||||||
|
// Generate a decomposition object handle
|
||||||
|
virtual void genDecomposition(int& decomp) = 0;
|
||||||
|
// Delete decomposition object handle
|
||||||
|
virtual void deleteDecomposition(int decomp) = 0;
|
||||||
|
// Bind given decomposition handle
|
||||||
|
// Commands operate on currently bound decomposition
|
||||||
|
virtual void bindDecomposition(int decomp) = 0;
|
||||||
|
|
||||||
|
// Sets *paramsOut to the address of the LLCDParam array and returns
|
||||||
|
// the number of parameters
|
||||||
|
virtual int getParameters(const LLCDParam** paramsOut) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Sets *stagesOut to the address of the LLCDStageData array and returns
|
||||||
|
// the number of stages
|
||||||
|
virtual int getStages(const LLCDStageData** stagesOut) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Set a parameter by name. Pass enum values as integers.
|
||||||
|
virtual LLCDResult setParam(const char* name, float val) = 0;
|
||||||
|
virtual LLCDResult setParam(const char* name, int val) = 0;
|
||||||
|
virtual LLCDResult setParam(const char* name, bool val) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Set incoming mesh data. Data is copied to local buffers and will
|
||||||
|
// persist until the next setMeshData call
|
||||||
|
virtual LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based ) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Register a callback to be called periodically during the specified stage
|
||||||
|
// See the typedef above for more information
|
||||||
|
virtual LLCDResult registerCallback( int stage, llcdCallbackFunc callback ) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Execute the specified decomposition stage
|
||||||
|
virtual LLCDResult executeStage(int stage) = 0;
|
||||||
|
virtual LLCDResult buildSingleHull() = 0 ;
|
||||||
|
|
||||||
|
|
||||||
|
// Gets the number of hulls generated by the specified decompositions stage
|
||||||
|
virtual int getNumHullsFromStage(int stage) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Populates hullOut to reference the internal copy of the requested hull
|
||||||
|
// The data will persist only until the next executeStage call for that stage.
|
||||||
|
virtual LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut ) = 0;
|
||||||
|
virtual LLCDResult getSingleHull( LLCDHull* hullOut ) = 0 ;
|
||||||
|
|
||||||
|
// TODO: Implement lock of some kind to disallow this call if data not yet ready
|
||||||
|
// Populates the meshDataOut to reference the utility's copy of the mesh geometry
|
||||||
|
// for the hull and stage specified.
|
||||||
|
// You must copy this data if you want to continue using it after the next executeStage
|
||||||
|
// call
|
||||||
|
virtual LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Creates a mesh from hullIn and temporarily stores it internally in the utility.
|
||||||
|
// The mesh data persists only until the next call to getMeshFromHull
|
||||||
|
virtual LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut ) = 0;
|
||||||
|
|
||||||
|
// Takes meshIn, generates a single convex hull from it, converts that to a mesh
|
||||||
|
// stored internally, and populates meshOut to reference the internally stored data.
|
||||||
|
// The data is persistent only until the next call to generateSingleHullMeshFromMesh
|
||||||
|
virtual LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut) = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
/// Debug
|
||||||
|
virtual void loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut) = 0;
|
||||||
|
|
||||||
|
virtual bool isFunctional()=0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool s_isInitialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pull in our trace interface
|
||||||
|
#include "ndConvexDecomposition.h"
|
||||||
|
|
||||||
|
#endif //LL_CONVEX_DECOMPOSITION
|
||||||
|
|
||||||
148
indra/libndhacd/LLConvexDecompositionStubImpl.cpp
Normal file
148
indra/libndhacd/LLConvexDecompositionStubImpl.cpp
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
* @file LLConvexDecompositionStubImpl.cpp
|
||||||
|
* @author falcon@lindenlab.com
|
||||||
|
* @brief A stub implementation of LLConvexDecomposition
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <memory>
|
||||||
|
#include "LLConvexDecompositionStubImpl.h"
|
||||||
|
|
||||||
|
LLConvexDecomposition* LLConvexDecompositionImpl::getInstance()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::initSystem()
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::initThread()
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::quitThread()
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::quitSystem()
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLConvexDecompositionImpl::genDecomposition(int& decomp)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLConvexDecompositionImpl::deleteDecomposition(int decomp)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLConvexDecompositionImpl::bindDecomposition(int decomp)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::setParam(const char* name, float val)
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::setParam(const char* name, bool val)
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::setParam(const char* name, int val)
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::setMeshData( const LLCDMeshData* data, bool vertex_based )
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::registerCallback(int stage, llcdCallbackFunc callback )
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::buildSingleHull()
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::executeStage(int stage)
|
||||||
|
{
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LLConvexDecompositionImpl::getNumHullsFromStage(int stage)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::getSingleHull( LLCDHull* hullOut )
|
||||||
|
{
|
||||||
|
memset( hullOut, 0, sizeof(LLCDHull) );
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::getHullFromStage( int stage, int hull, LLCDHull* hullOut )
|
||||||
|
{
|
||||||
|
memset( hullOut, 0, sizeof(LLCDHull) );
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut )
|
||||||
|
{
|
||||||
|
memset( meshDataOut, 0, sizeof(LLCDMeshData) );
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut )
|
||||||
|
{
|
||||||
|
memset( meshOut, 0, sizeof(LLCDMeshData) );
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult LLConvexDecompositionImpl::generateSingleHullMeshFromMesh(LLCDMeshData* meshIn, LLCDMeshData* meshOut)
|
||||||
|
{
|
||||||
|
memset( meshOut, 0, sizeof(LLCDMeshData) );
|
||||||
|
return LLCD_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLConvexDecompositionImpl::loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut)
|
||||||
|
{
|
||||||
|
static LLCDMeshData meshData;
|
||||||
|
memset( &meshData, 0, sizeof(LLCDMeshData) );
|
||||||
|
*meshDataOut = &meshData;
|
||||||
|
}
|
||||||
97
indra/libndhacd/LLConvexDecompositionStubImpl.h
Normal file
97
indra/libndhacd/LLConvexDecompositionStubImpl.h
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* @file LLConvexDecompositionStubImpl.h
|
||||||
|
* @author falcon@lindenlab.com
|
||||||
|
* @brief A stub implementation of LLConvexDecomposition
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LL_CONVEX_DECOMP_UTIL_H
|
||||||
|
#define LL_CONVEX_DECOMP_UTIL_H
|
||||||
|
|
||||||
|
#include "LLConvexDecomposition.h"
|
||||||
|
|
||||||
|
class LLConvexDecompositionImpl : public LLConvexDecomposition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~LLConvexDecompositionImpl() {}
|
||||||
|
|
||||||
|
static LLConvexDecomposition* getInstance();
|
||||||
|
static LLCDResult initSystem();
|
||||||
|
static LLCDResult initThread();
|
||||||
|
static LLCDResult quitThread();
|
||||||
|
static LLCDResult quitSystem();
|
||||||
|
|
||||||
|
// Generate a decomposition object handle
|
||||||
|
void genDecomposition(int& decomp);
|
||||||
|
// Delete decomposition object handle
|
||||||
|
void deleteDecomposition(int decomp);
|
||||||
|
// Bind given decomposition handle
|
||||||
|
// Commands operate on currently bound decomposition
|
||||||
|
void bindDecomposition(int decomp);
|
||||||
|
|
||||||
|
// Sets *paramsOut to the address of the LLCDParam array and returns
|
||||||
|
// the length of the array
|
||||||
|
int getParameters(const LLCDParam** paramsOut)
|
||||||
|
{
|
||||||
|
*paramsOut = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getStages(const LLCDStageData** stagesOut)
|
||||||
|
{
|
||||||
|
*stagesOut = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a parameter by name. Returns false if out of bounds or unsupported parameter
|
||||||
|
LLCDResult setParam(const char* name, float val);
|
||||||
|
LLCDResult setParam(const char* name, int val);
|
||||||
|
LLCDResult setParam(const char* name, bool val);
|
||||||
|
LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based );
|
||||||
|
LLCDResult registerCallback(int stage, llcdCallbackFunc callback );
|
||||||
|
|
||||||
|
LLCDResult executeStage(int stage);
|
||||||
|
LLCDResult buildSingleHull() ;
|
||||||
|
|
||||||
|
int getNumHullsFromStage(int stage);
|
||||||
|
|
||||||
|
LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut );
|
||||||
|
LLCDResult getSingleHull( LLCDHull* hullOut ) ;
|
||||||
|
|
||||||
|
// TODO: Implement lock of some kind to disallow this call if data not yet ready
|
||||||
|
LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut);
|
||||||
|
LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut );
|
||||||
|
|
||||||
|
// For visualizing convex hull shapes in the viewer physics shape display
|
||||||
|
LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut);
|
||||||
|
|
||||||
|
/// Debug
|
||||||
|
void loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LLConvexDecompositionImpl() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //LL_CONVEX_DECOMP_UTIL_H
|
||||||
58
indra/libndhacd/ndConvexDecomposition.h
Normal file
58
indra/libndhacd/ndConvexDecomposition.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef ND_CONVEXDECOMPOSITION_H
|
||||||
|
#define ND_CONVEXDECOMPOSITION_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copyright 2011 sl.nicky.ml@googlemail.com
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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 ND_HASCONVEXDECOMP_TRACER
|
||||||
|
#define ND_HASCONVEXDECOMP_TRACER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ndConvexDecompositionTracer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ETraceLevel
|
||||||
|
{
|
||||||
|
eNone = 0,
|
||||||
|
eTraceFunctions = 0x1,
|
||||||
|
eTraceData = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~ndConvexDecompositionTracer()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void trace( char const *a_strMsg ) = 0;
|
||||||
|
|
||||||
|
virtual void startTraceData( char const *a_strWhat) = 0;
|
||||||
|
virtual void traceData( char const *a_strData ) = 0;
|
||||||
|
virtual void endTraceData() = 0;
|
||||||
|
|
||||||
|
virtual int getLevel() = 0;
|
||||||
|
|
||||||
|
virtual void addref() = 0;
|
||||||
|
virtual void release() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ndConvexDecompositionTracable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void setTracer( ndConvexDecompositionTracer *) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
51
indra/libndhacd/nd_EnterExitTracer.cpp
Normal file
51
indra/libndhacd/nd_EnterExitTracer.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* copyright 2011 sl.nicky.ml@googlemail.com
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nd_EnterExitTracer.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
void EnterExitTracer::doTrace( char const *aPrefix )
|
||||||
|
{
|
||||||
|
if( !mFunc || !mTracer )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( ndConvexDecompositionTracer::eTraceFunctions == (mTracer->getLevel() & ndConvexDecompositionTracer::eTraceFunctions ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
if( aPrefix )
|
||||||
|
str << aPrefix;
|
||||||
|
|
||||||
|
str << mFunc;
|
||||||
|
mTracer->trace( str.str().c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterExitTracer::EnterExitTracer( char const *aFunc, ndConvexDecompositionTracer *aTracer )
|
||||||
|
: mFunc( aFunc )
|
||||||
|
, mTracer( aTracer )
|
||||||
|
{
|
||||||
|
doTrace( "enter: " );
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterExitTracer::~EnterExitTracer( )
|
||||||
|
{
|
||||||
|
doTrace( "exit: " );
|
||||||
|
}
|
||||||
|
|
||||||
43
indra/libndhacd/nd_EnterExitTracer.h
Normal file
43
indra/libndhacd/nd_EnterExitTracer.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef ND_ENTEREXITTRACER_H
|
||||||
|
#define ND_ENTEREXITTRACER_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copyright 2011 sl.nicky.ml@googlemail.com
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ndConvexDecomposition.h"
|
||||||
|
|
||||||
|
class EnterExitTracer
|
||||||
|
{
|
||||||
|
char const *mFunc;
|
||||||
|
ndConvexDecompositionTracer *mTracer;
|
||||||
|
|
||||||
|
void doTrace( char const *aPrefix );
|
||||||
|
|
||||||
|
public:
|
||||||
|
EnterExitTracer( char const *aFunc, ndConvexDecompositionTracer *aTracer );
|
||||||
|
~EnterExitTracer( );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define TRACE_FUNC(ATRACER) EnterExitTracer oETTrace( __PRETTY_FUNCTION__, ATRACER );
|
||||||
|
#else
|
||||||
|
#define TRACE_FUNC(ATRACER) EnterExitTracer oETTrace( __FUNCTION__, ATRACER );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
188
indra/libndhacd/nd_StructTracer.cpp
Normal file
188
indra/libndhacd/nd_StructTracer.cpp
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
/**
|
||||||
|
* copyright 2011 sl.nicky.ml@googlemail.com
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nd_StructTracer.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace ndStructTracer
|
||||||
|
{
|
||||||
|
bool doTrace( ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
if( !aTracer )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ndConvexDecompositionTracer::eTraceData == (aTracer->getLevel() & ndConvexDecompositionTracer::eTraceData) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T> void traceVecDbl( T const &aValue, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
stringstream str;
|
||||||
|
str << fixed
|
||||||
|
<< "\tX: " << aValue.X()
|
||||||
|
<< " Y: " << aValue.Y()
|
||||||
|
<< " Z: " << aValue.Z();
|
||||||
|
|
||||||
|
aTracer->traceData( str.str().c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T> void traceVecDoubles( vector< T > const &aVertices, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < aVertices.size(); ++i )
|
||||||
|
traceVecDbl( aVertices[i], aTracer );
|
||||||
|
}
|
||||||
|
|
||||||
|
void traceVertices( vector< tVecDbl > const &aVertices, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
aTracer->traceData( "Triangles\n" );
|
||||||
|
traceVecDoubles( aVertices, aTracer );
|
||||||
|
}
|
||||||
|
|
||||||
|
void traceTriangles( vector< tVecLong > const &aTriangles, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
aTracer->traceData( "Vertices\n" );
|
||||||
|
traceVecDoubles( aTriangles, aTracer );
|
||||||
|
}
|
||||||
|
|
||||||
|
void trace( DecompData const &aData, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
if( !doTrace( aTracer ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
aTracer->startTraceData("Hulls");
|
||||||
|
|
||||||
|
stringstream str;
|
||||||
|
str << "Hulls: " << aData.mHulls.size();
|
||||||
|
aTracer->traceData( str.str().c_str() );
|
||||||
|
str.seekp(0);
|
||||||
|
|
||||||
|
for( size_t i = 0; i < aData.mHulls.size(); ++i )
|
||||||
|
{
|
||||||
|
str << "Hull #" << i;
|
||||||
|
aTracer->traceData( str.str().c_str() );
|
||||||
|
str.seekp(0);
|
||||||
|
|
||||||
|
DecompHull const &oHull( aData.mHulls[i] );
|
||||||
|
traceVertices( oHull.mVertices, aTracer );
|
||||||
|
traceTriangles( oHull.mTriangles, aTracer );
|
||||||
|
}
|
||||||
|
|
||||||
|
aTracer->endTraceData();
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T> void traceVertex( T aX, T aY, T aZ, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
stringstream str;
|
||||||
|
str << fixed
|
||||||
|
<< "X: " << aX
|
||||||
|
<< "Y: " << aY
|
||||||
|
<< "Z: " << aZ;
|
||||||
|
|
||||||
|
aTracer->traceData( str.str().c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T> void traceTriangle( void *& aPtr, int aStride, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
T *pData = reinterpret_cast< T* >(aPtr);
|
||||||
|
long X( pData[0] ), Y( pData[1] ), Z( pData[2] );
|
||||||
|
|
||||||
|
traceVertex( X, Y, Z, aTracer );
|
||||||
|
|
||||||
|
pData += aStride;
|
||||||
|
aPtr = pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void traceVertices( int aNumVertices, float const *aVertices, int aStride, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < aNumVertices; ++i )
|
||||||
|
{
|
||||||
|
float X( aVertices[0] ), Y( aVertices[1] ), Z( aVertices[2] );
|
||||||
|
traceVertex( X, Y, Z, aTracer );
|
||||||
|
aVertices += aStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void traceTriangles( LLCDMeshData const *aData, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
int nCount = aData->mNumTriangles;
|
||||||
|
int nStride = aData->mIndexStrideBytes;
|
||||||
|
void *pData = const_cast<void*>( aData->mIndexBase );
|
||||||
|
int nIndexType = aData->mIndexType;
|
||||||
|
|
||||||
|
if ( LLCDMeshData::INT_16 == nIndexType )
|
||||||
|
nStride /= 2;
|
||||||
|
else
|
||||||
|
nStride /= 4;
|
||||||
|
|
||||||
|
for ( int i = 0; i < nCount; ++i )
|
||||||
|
{
|
||||||
|
if( LLCDMeshData::INT_16 == nIndexType )
|
||||||
|
traceTriangle< hacdUINT16 >( pData, nStride, aTracer );
|
||||||
|
else
|
||||||
|
traceTriangle< hacdUINT32 >( pData, nStride, aTracer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trace( LLCDMeshData const *aData, bool aVertexBased, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
if( !doTrace( aTracer ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
aTracer->startTraceData("LLCDMeshData");
|
||||||
|
|
||||||
|
string strVBased("true");
|
||||||
|
if( !aVertexBased )
|
||||||
|
strVBased = "false";
|
||||||
|
|
||||||
|
stringstream str;
|
||||||
|
str << "LLCDMeshData vertex based: " << strVBased
|
||||||
|
<< "# vertices " << aData->mNumVertices
|
||||||
|
<< "# triangles " << aData->mNumTriangles;
|
||||||
|
|
||||||
|
aTracer->traceData( str.str().c_str() );
|
||||||
|
|
||||||
|
traceVertices( aData->mNumVertices, aData->mVertexBase, aData->mVertexStrideBytes/sizeof(float), aTracer );
|
||||||
|
|
||||||
|
if( !aVertexBased )
|
||||||
|
traceTriangles( aData, aTracer );
|
||||||
|
|
||||||
|
aTracer->endTraceData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trace( LLCDHull const *aData, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
if( !doTrace( aTracer ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
aTracer->startTraceData("LLCDHull");
|
||||||
|
|
||||||
|
stringstream str;
|
||||||
|
str << "LLCDHull # vertices " << aData->mNumVertices;
|
||||||
|
|
||||||
|
aTracer->traceData( str.str().c_str() );
|
||||||
|
|
||||||
|
traceVertices( aData->mNumVertices, aData->mVertexBase, aData->mVertexStrideBytes/sizeof(float), aTracer );
|
||||||
|
|
||||||
|
|
||||||
|
aTracer->endTraceData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
34
indra/libndhacd/nd_StructTracer.h
Normal file
34
indra/libndhacd/nd_StructTracer.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef ND_STRUCTTRACER_H
|
||||||
|
#define ND_STRUCTTRACER_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copyright 2011 sl.nicky.ml@googlemail.com
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ndConvexDecomposition.h"
|
||||||
|
#include "LLConvexDecomposition.h"
|
||||||
|
#include "nd_hacdStructs.h"
|
||||||
|
|
||||||
|
namespace ndStructTracer
|
||||||
|
{
|
||||||
|
void trace( DecompData const &aData, ndConvexDecompositionTracer *aTracer );
|
||||||
|
void trace( LLCDMeshData const *aData, bool aVertexBased, ndConvexDecompositionTracer *aTracer );
|
||||||
|
void trace( LLCDHull const *aData, ndConvexDecompositionTracer *aTracer );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
393
indra/libndhacd/nd_hacdConvexDecomposition.cpp
Normal file
393
indra/libndhacd/nd_hacdConvexDecomposition.cpp
Normal file
@@ -0,0 +1,393 @@
|
|||||||
|
/**
|
||||||
|
* copyright 2011 sl.nicky.ml@googlemail.com
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <memory>
|
||||||
|
#include "nd_hacdConvexDecomposition.h"
|
||||||
|
|
||||||
|
#include "nd_hacdDefines.h"
|
||||||
|
#include "nd_hacdStructs.h"
|
||||||
|
#include "nd_hacdUtils.h"
|
||||||
|
#include "ndConvexDecomposition.h"
|
||||||
|
#include "nd_EnterExitTracer.h"
|
||||||
|
#include "nd_StructTracer.h"
|
||||||
|
|
||||||
|
LLCDStageData nd_hacdConvexDecomposition::mStages[1];
|
||||||
|
|
||||||
|
LLCDParam nd_hacdConvexDecomposition::mParams[4];
|
||||||
|
LLCDParam::LLCDEnumItem nd_hacdConvexDecomposition::mMethods[1];
|
||||||
|
LLCDParam::LLCDEnumItem nd_hacdConvexDecomposition::mQuality[1];
|
||||||
|
LLCDParam::LLCDEnumItem nd_hacdConvexDecomposition::mSimplify[1];
|
||||||
|
|
||||||
|
LLConvexDecomposition* nd_hacdConvexDecomposition::getInstance()
|
||||||
|
{
|
||||||
|
static nd_hacdConvexDecomposition sImpl;
|
||||||
|
return &sImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
nd_hacdConvexDecomposition::nd_hacdConvexDecomposition()
|
||||||
|
{
|
||||||
|
mNextId = 0;
|
||||||
|
mCurrentDecoder = 0;
|
||||||
|
mSingleHullMeshFromMesh = new HACDDecoder();
|
||||||
|
mTracer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nd_hacdConvexDecomposition::~nd_hacdConvexDecomposition()
|
||||||
|
{
|
||||||
|
if( mTracer )
|
||||||
|
mTracer->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::initSystem()
|
||||||
|
{
|
||||||
|
memset( &mStages[0], 0, sizeof( mStages ) );
|
||||||
|
memset( &mParams[0], 0, sizeof( mParams ) );
|
||||||
|
memset( &mMethods[0], 0, sizeof( mMethods ) );
|
||||||
|
memset( &mQuality[0], 0, sizeof( mQuality ) );
|
||||||
|
memset( &mSimplify[0], 0, sizeof( mSimplify ) );
|
||||||
|
|
||||||
|
mStages[0].mName = "Decompose";
|
||||||
|
mStages[0].mDescription = NULL;
|
||||||
|
|
||||||
|
mMethods[0].mName = "Default";
|
||||||
|
mMethods[0].mValue = 0;
|
||||||
|
|
||||||
|
mQuality[0].mName = "Default";
|
||||||
|
mQuality[0].mValue = 0;
|
||||||
|
|
||||||
|
mSimplify[0].mName = "None";
|
||||||
|
mSimplify[0].mValue = 0;
|
||||||
|
|
||||||
|
mParams[0].mName = "nd_AlwaysNeedTriangles";
|
||||||
|
mParams[0].mDescription = 0;
|
||||||
|
mParams[0].mType = LLCDParam::LLCD_BOOLEAN;
|
||||||
|
mParams[0].mDefault.mBool = true;
|
||||||
|
|
||||||
|
mParams[1].mName = "Method";
|
||||||
|
mParams[1].mType = LLCDParam::LLCD_ENUM;
|
||||||
|
mParams[1].mDetails.mEnumValues.mNumEnums = sizeof(mMethods)/sizeof(LLCDParam::LLCDEnumItem);
|
||||||
|
mParams[1].mDetails.mEnumValues.mEnumsArray = mMethods;
|
||||||
|
mParams[1].mDefault.mIntOrEnumValue = 0;
|
||||||
|
|
||||||
|
mParams[2].mName = "Decompose Quality";
|
||||||
|
mParams[2].mType = LLCDParam::LLCD_ENUM;
|
||||||
|
mParams[2].mDetails.mEnumValues.mNumEnums = sizeof(mQuality)/sizeof(LLCDParam::LLCDEnumItem);
|
||||||
|
mParams[2].mDetails.mEnumValues.mEnumsArray = mQuality;
|
||||||
|
mParams[2].mDefault.mIntOrEnumValue = 0;
|
||||||
|
|
||||||
|
mParams[3].mName = "Simplify Method";
|
||||||
|
mParams[3].mType = LLCDParam::LLCD_ENUM;
|
||||||
|
mParams[3].mDetails.mEnumValues.mNumEnums = sizeof(mSimplify)/sizeof(LLCDParam::LLCDEnumItem);
|
||||||
|
mParams[3].mDetails.mEnumValues.mEnumsArray = mSimplify;
|
||||||
|
mParams[3].mDefault.mIntOrEnumValue = 0;
|
||||||
|
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::initThread()
|
||||||
|
{
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::quitThread()
|
||||||
|
{
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::quitSystem()
|
||||||
|
{
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nd_hacdConvexDecomposition::genDecomposition( int& decomp )
|
||||||
|
{
|
||||||
|
HACDDecoder *pGen = new HACDDecoder();
|
||||||
|
decomp = mNextId;
|
||||||
|
++mNextId;
|
||||||
|
|
||||||
|
mDecoders[ decomp ] = pGen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nd_hacdConvexDecomposition::deleteDecomposition( int decomp )
|
||||||
|
{
|
||||||
|
delete mDecoders[ decomp ];
|
||||||
|
mDecoders.erase( decomp );
|
||||||
|
}
|
||||||
|
|
||||||
|
void nd_hacdConvexDecomposition::bindDecomposition( int decomp )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
mCurrentDecoder = decomp;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::setParam( const char* name, float val )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::setParam( const char* name, bool val )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::setParam( const char* name, int val )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::setMeshData( const LLCDMeshData* data, bool vertex_based )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
ndStructTracer::trace( data, vertex_based, mTracer );
|
||||||
|
|
||||||
|
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
|
||||||
|
return ::setMeshData( data, vertex_based, pC );
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::registerCallback( int stage, llcdCallbackFunc callback )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
if( mDecoders.end() == mDecoders.find( mCurrentDecoder ) )
|
||||||
|
return LLCD_STAGE_NOT_READY;
|
||||||
|
|
||||||
|
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
|
||||||
|
pC->mCallback = callback;
|
||||||
|
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::buildSingleHull()
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::executeStage( int stage )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
if ( stage < 0 || stage >= NUM_STAGES )
|
||||||
|
return LLCD_INVALID_STAGE;
|
||||||
|
|
||||||
|
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
|
||||||
|
tHACD *pHACD = init( 1, MIN_NUMBER_OF_CLUSTERS, MAX_VERTICES_PER_HULL, CONNECT_DISTS[0], pC );
|
||||||
|
|
||||||
|
DecompData oRes = decompose( pHACD );
|
||||||
|
ndStructTracer::trace( oRes, mTracer );
|
||||||
|
|
||||||
|
delete pHACD;
|
||||||
|
|
||||||
|
pC->mStages[ stage ] = oRes;
|
||||||
|
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nd_hacdConvexDecomposition::getNumHullsFromStage( int stage )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
|
||||||
|
|
||||||
|
if ( !pC )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( stage < 0 || static_cast<size_t>(stage) >= pC->mStages.size() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return pC->mStages[stage].mHulls.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
DecompData toSingleHull( HACDDecoder *aDecoder, LLCDResult &aRes, ndConvexDecompositionTracer *aTracer )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( aTracer );
|
||||||
|
aRes = LLCD_REQUEST_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
for ( int i = 0; i < TO_SINGLE_HULL_TRIES; ++i )
|
||||||
|
{
|
||||||
|
tHACD *pHACD = init( CONCAVITY_FOR_SINGLE_HULL[i], 1, MAX_VERTICES_PER_HULL, CONNECT_DISTS[i], aDecoder );
|
||||||
|
|
||||||
|
DecompData oRes = decompose( pHACD );
|
||||||
|
delete pHACD;
|
||||||
|
|
||||||
|
ndStructTracer::trace( oRes, aTracer );
|
||||||
|
|
||||||
|
if ( oRes.mHulls.size() == 1 )
|
||||||
|
{
|
||||||
|
aRes = LLCD_OK;
|
||||||
|
return oRes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DecompData();
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::getSingleHull( LLCDHull* hullOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
|
||||||
|
|
||||||
|
memset( hullOut, 0, sizeof( LLCDHull ) );
|
||||||
|
|
||||||
|
LLCDResult res;
|
||||||
|
|
||||||
|
// Will already trace oRes
|
||||||
|
DecompData oRes = ::toSingleHull( pC, res, mTracer );
|
||||||
|
|
||||||
|
if ( LLCD_OK != res || oRes.mHulls.size() != 1 )
|
||||||
|
return res;
|
||||||
|
|
||||||
|
pC->mSingleHull = oRes.mHulls[0];
|
||||||
|
pC->mSingleHull.toLLHull( hullOut );
|
||||||
|
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::getHullFromStage( int stage, int hull, LLCDHull* hullOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
|
||||||
|
|
||||||
|
memset( hullOut, 0, sizeof( LLCDHull ) );
|
||||||
|
|
||||||
|
if ( stage < 0 || static_cast<size_t>(stage) >= pC->mStages.size() )
|
||||||
|
return LLCD_INVALID_STAGE;
|
||||||
|
|
||||||
|
DecompData &oData = pC->mStages[ stage ];
|
||||||
|
|
||||||
|
if ( hull < 0 ||static_cast<size_t>(hull) >= oData.mHulls.size() )
|
||||||
|
return LLCD_REQUEST_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
oData.mHulls[ hull ].toLLHull( hullOut );
|
||||||
|
ndStructTracer::trace( hullOut, mTracer );
|
||||||
|
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
|
||||||
|
|
||||||
|
memset( meshDataOut, 0, sizeof( LLCDHull ) );
|
||||||
|
|
||||||
|
if ( stage < 0 || static_cast<size_t>(stage) >= pC->mStages.size() )
|
||||||
|
return LLCD_INVALID_STAGE;
|
||||||
|
|
||||||
|
DecompData &oData = pC->mStages[ stage ];
|
||||||
|
|
||||||
|
if ( hull < 0 || static_cast<size_t>(hull) >= oData.mHulls.size() )
|
||||||
|
return LLCD_REQUEST_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
oData.mHulls[ hull ].toLLMesh( meshDataOut );
|
||||||
|
ndStructTracer::trace( meshDataOut, true, mTracer );
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
memset( meshOut, 0, sizeof( LLCDMeshData ) );
|
||||||
|
|
||||||
|
mMeshToHullVertices.clear();
|
||||||
|
mMeshToHullTriangles.clear();
|
||||||
|
|
||||||
|
if( !hullIn || !hullIn->mVertexBase || !meshOut )
|
||||||
|
return LLCD_NULL_PTR;
|
||||||
|
if( hullIn->mVertexStrideBytes < 3*sizeof(float) || hullIn->mNumVertices < 3 )
|
||||||
|
return LLCD_INVALID_HULL_DATA;
|
||||||
|
|
||||||
|
LLCDResult oRet = convertHullToMesh( hullIn, mMeshToHullVertices, mMeshToHullTriangles );
|
||||||
|
|
||||||
|
if( LLCD_OK != oRet )
|
||||||
|
return oRet;
|
||||||
|
|
||||||
|
meshOut->mVertexStrideBytes = sizeof( float )*3;
|
||||||
|
meshOut->mNumVertices = mMeshToHullVertices.size()/3;
|
||||||
|
meshOut->mVertexBase = &mMeshToHullVertices[0];
|
||||||
|
|
||||||
|
meshOut->mIndexType = LLCDMeshData::INT_32;
|
||||||
|
meshOut->mIndexStrideBytes = sizeof( hacdUINT32 ) * 3;
|
||||||
|
meshOut->mNumTriangles = mMeshToHullTriangles.size()/3;
|
||||||
|
meshOut->mIndexBase = &mMeshToHullTriangles[0];
|
||||||
|
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLCDResult nd_hacdConvexDecomposition::generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
memset( meshOut, 0, sizeof( LLCDMeshData ) );
|
||||||
|
mSingleHullMeshFromMesh->clear();
|
||||||
|
LLCDResult res = ::setMeshData( meshIn, meshIn->mNumVertices > 3, mSingleHullMeshFromMesh );
|
||||||
|
|
||||||
|
if ( LLCD_OK != res )
|
||||||
|
return res;
|
||||||
|
|
||||||
|
// Will already trace oRes
|
||||||
|
DecompData oRes = ::toSingleHull( mSingleHullMeshFromMesh, res, mTracer );
|
||||||
|
|
||||||
|
if ( LLCD_OK != res || oRes.mHulls.size() != 1 )
|
||||||
|
return res;
|
||||||
|
|
||||||
|
mSingleHullMeshFromMesh->mSingleHull = oRes.mHulls[0];
|
||||||
|
mSingleHullMeshFromMesh->mSingleHull.toLLMesh( meshOut );
|
||||||
|
|
||||||
|
return LLCD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nd_hacdConvexDecomposition::loadMeshData( const char* fileIn, LLCDMeshData** meshDataOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
static LLCDMeshData meshData;
|
||||||
|
memset( &meshData, 0, sizeof( LLCDMeshData ) );
|
||||||
|
*meshDataOut = &meshData;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nd_hacdConvexDecomposition::getParameters( const LLCDParam** paramsOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
*paramsOut = mParams;
|
||||||
|
return sizeof(mParams)/sizeof(LLCDParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nd_hacdConvexDecomposition::getStages( const LLCDStageData** stagesOut )
|
||||||
|
{
|
||||||
|
TRACE_FUNC( mTracer );
|
||||||
|
|
||||||
|
*stagesOut = mStages;
|
||||||
|
return sizeof(mStages)/sizeof(LLCDStageData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nd_hacdConvexDecomposition::setTracer( ndConvexDecompositionTracer * aTracer)
|
||||||
|
{
|
||||||
|
if( mTracer )
|
||||||
|
mTracer->release();
|
||||||
|
|
||||||
|
mTracer = aTracer;
|
||||||
|
|
||||||
|
if( mTracer )
|
||||||
|
mTracer->addref();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool nd_hacdConvexDecomposition::isFunctional()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
103
indra/libndhacd/nd_hacdConvexDecomposition.h
Normal file
103
indra/libndhacd/nd_hacdConvexDecomposition.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* copyright 2011 sl.nicky.ml@googlemail.com
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* 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 ND_HACD_CONVEXDECOMP_H
|
||||||
|
#define ND_HACD_CONVEXDECOMP_H
|
||||||
|
|
||||||
|
#include "LLConvexDecomposition.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct HACDDecoder;
|
||||||
|
|
||||||
|
class nd_hacdConvexDecomposition : public LLConvexDecomposition, public ndConvexDecompositionTracable
|
||||||
|
{
|
||||||
|
int mNextId;
|
||||||
|
int mCurrentDecoder;
|
||||||
|
std::map< int, HACDDecoder * > mDecoders;
|
||||||
|
HACDDecoder *mSingleHullMeshFromMesh;
|
||||||
|
|
||||||
|
std::vector< float > mMeshToHullVertices;
|
||||||
|
std::vector< int > mMeshToHullTriangles;
|
||||||
|
|
||||||
|
ndConvexDecompositionTracer *mTracer;
|
||||||
|
|
||||||
|
static LLCDStageData mStages[1];
|
||||||
|
|
||||||
|
static LLCDParam mParams[4];
|
||||||
|
static LLCDParam::LLCDEnumItem mMethods[1];
|
||||||
|
static LLCDParam::LLCDEnumItem mQuality[1];
|
||||||
|
static LLCDParam::LLCDEnumItem mSimplify[1];
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~nd_hacdConvexDecomposition();
|
||||||
|
|
||||||
|
static LLConvexDecomposition* getInstance();
|
||||||
|
static LLCDResult initSystem();
|
||||||
|
static LLCDResult initThread();
|
||||||
|
static LLCDResult quitThread();
|
||||||
|
static LLCDResult quitSystem();
|
||||||
|
|
||||||
|
// Generate a decomposition object handle
|
||||||
|
void genDecomposition( int& decomp );
|
||||||
|
// Delete decomposition object handle
|
||||||
|
void deleteDecomposition( int decomp );
|
||||||
|
// Bind given decomposition handle
|
||||||
|
// Commands operate on currently bound decomposition
|
||||||
|
void bindDecomposition( int decomp );
|
||||||
|
|
||||||
|
// Sets *paramsOut to the address of the LLCDParam array and returns
|
||||||
|
// the length of the array
|
||||||
|
int getParameters( const LLCDParam** paramsOut );
|
||||||
|
int getStages( const LLCDStageData** stagesOut ) ;
|
||||||
|
|
||||||
|
// Set a parameter by name. Returns false if out of bounds or unsupported parameter
|
||||||
|
LLCDResult setParam( const char* name, float val );
|
||||||
|
LLCDResult setParam( const char* name, int val );
|
||||||
|
LLCDResult setParam( const char* name, bool val );
|
||||||
|
LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based );
|
||||||
|
LLCDResult registerCallback( int stage, llcdCallbackFunc callback );
|
||||||
|
|
||||||
|
LLCDResult executeStage( int stage );
|
||||||
|
LLCDResult buildSingleHull() ;
|
||||||
|
|
||||||
|
int getNumHullsFromStage( int stage );
|
||||||
|
|
||||||
|
LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut );
|
||||||
|
LLCDResult getSingleHull( LLCDHull* hullOut ) ;
|
||||||
|
|
||||||
|
// TODO: Implement lock of some kind to disallow this call if data not yet ready
|
||||||
|
LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut );
|
||||||
|
LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut );
|
||||||
|
|
||||||
|
// For visualizing convex hull shapes in the viewer physics shape display
|
||||||
|
LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut );
|
||||||
|
|
||||||
|
/// Debug
|
||||||
|
void loadMeshData( const char* fileIn, LLCDMeshData** meshDataOut );
|
||||||
|
|
||||||
|
virtual void setTracer( ndConvexDecompositionTracer *);
|
||||||
|
|
||||||
|
virtual bool isFunctional();
|
||||||
|
|
||||||
|
private:
|
||||||
|
nd_hacdConvexDecomposition();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user