Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast picking with an octree 🎉 #9961

Closed
wants to merge 120 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
6012a5f
initial
IanLilleyT May 9, 2020
b95cbd2
fixed 2 bugs
IanLilleyT May 9, 2020
c7a8786
fixed some bugs
IanLilleyT May 10, 2020
e150206
sadncastle improvements
IanLilleyT May 16, 2020
cc7e38c
faster traversal
IanLilleyT May 17, 2020
ba4aff8
small optimization pass
IanLilleyT May 17, 2020
d9546f4
more balanced binning
IanLilleyT May 18, 2020
0c2beca
alternate construction that may be faster
IanLilleyT May 18, 2020
921ac1c
made bit logic faster
IanLilleyT May 19, 2020
b82f5d2
minor
IanLilleyT May 19, 2020
ba2919d
added getTriVertsFromIndex
IanLilleyT May 20, 2020
454d06c
fixed scratch var bug
IanLilleyT May 21, 2020
d13bd0c
claeanup
IanLilleyT May 21, 2020
ba6d133
better support for backfaces
IanLilleyT May 21, 2020
09b1961
renamed filterdown variable names
IanLilleyT May 21, 2020
7b21e6e
removed timers from globesurfacetile
IanLilleyT May 21, 2020
99b90a1
not allocating the entire tri array up front
IanLilleyT May 21, 2020
75a6812
small optimiziation
IanLilleyT May 21, 2020
892bbe4
minor
IanLilleyT May 21, 2020
446307c
moved triangle picking to terrain mesh
IanLilleyT May 21, 2020
60e5164
clreanup and more doc
IanLilleyT May 21, 2020
22bb924
rename
IanLilleyT May 21, 2020
7e60cc6
picking in the worker for quantized mesh
IanLilleyT May 27, 2020
bdb276d
added support for heightmaps
IanLilleyT May 27, 2020
3aa7401
comment
IanLilleyT May 28, 2020
f1ce061
Merge branch 'master' into fastPicking
IanLilleyT Jun 3, 2020
d082644
Merge branch 'master' into fastPicking
DanielLeone Jul 24, 2020
161a675
moved the octree into array buffers before sending cross-thread
DanielLeone Jul 28, 2020
a17d601
turned back on the new picking
DanielLeone Jul 28, 2020
04387ec
lots of debugging changes, don't test with this commit; it won't work.
DanielLeone Aug 28, 2020
a7dd147
Merge remote-tracking branch 'upstream/master' into fastPicking2
DanielLeone Jan 8, 2021
19c6375
Merge remote-tracking branch 'origin/fix-arcgis-sample-terrain-height…
DanielLeone Jan 8, 2021
8ddbdb8
* hacked a few arguments in to Globe and GlobeSurfaceTile just for cr…
DanielLeone Jan 11, 2021
b42fe7f
* tried inlining - made everything works
DanielLeone Jan 12, 2021
a454c3c
Merge branch 'fix-arcgis-sample-terrain-height' into fastPicking2
DanielLeone Jan 14, 2021
a17a680
added special flags to puppeteer to capture v8 opts and de-opts
DanielLeone Jan 14, 2021
494fd9d
just a checkpoint
DanielLeone Jan 15, 2021
1ed774c
* updated parse_traces.js to output --last=n amount
DanielLeone Jan 15, 2021
1048196
undo the bitmask thing - again more testing
DanielLeone Jan 15, 2021
bd6a3af
wait I did that wrong I think.. now it's way slower
DanielLeone Jan 15, 2021
51db732
back to 2 functions
DanielLeone Jan 15, 2021
10c2d4b
* added commit hash to benchmark script
DanielLeone Jan 20, 2021
b391890
Merge remote-tracking branch 'upstream/master' into fastPicking2
DanielLeone Jan 20, 2021
52c16a0
updated tracing script to measure all timers
DanielLeone Jan 20, 2021
ee3759a
fixing up some es6 compile errors
DanielLeone Jan 20, 2021
63bc3d3
switched to using a packed triangle array instead of a js-object tria…
DanielLeone Jan 20, 2021
3a6d8cc
added flag to parse traces to print the logs
DanielLeone Jan 20, 2021
a0fad10
reverted - however we've still got the memory issues... hmmmmm what
DanielLeone Jan 20, 2021
737eb8d
fixed the perf regression - it was the .concat() call... apparently t…
DanielLeone Jan 20, 2021
01d5a0b
just went back to 2 axis overlap counts for now
DanielLeone Jan 20, 2021
9566943
cleaned up some interfaces a little - removed some methods.
DanielLeone Jan 21, 2021
eb3d6ba
added the pick method to the terrain mesh class so it can hide the tr…
DanielLeone Jan 21, 2021
192323e
removing some temporary code
DanielLeone Feb 3, 2021
9df18c8
Merge branch 'fix-arcgis-sample-terrain-height' into fastPicking2
DanielLeone Feb 3, 2021
25f7582
turned off old-picking behaviour with a bool for now
DanielLeone Feb 3, 2021
70e9b3a
optimized both heightmap triangle creation functions
DanielLeone Feb 4, 2021
d0cfece
swapped CWT to packed triangles as well
DanielLeone Feb 4, 2021
2380ce8
removed some unused code
DanielLeone Feb 4, 2021
43e67eb
deleting some stuff
DanielLeone Feb 4, 2021
0177f21
cleaning up some changes
DanielLeone Feb 4, 2021
23abe63
more reverts
DanielLeone Feb 4, 2021
ea15209
added what might be considered a test...
DanielLeone Feb 4, 2021
aadb8c2
added a test for ArcGIS - it fails and I have no idea why.
DanielLeone Feb 9, 2021
3c3756b
lots of debugging stuff; and some fixes
DanielLeone Feb 15, 2021
6cfefad
lots of reverts - still a failing test
DanielLeone Feb 15, 2021
4e6fc4c
figured out what was wrong with the test
DanielLeone Feb 16, 2021
8e0b99e
nuked all the octree traversal code - now just looping through all no…
DanielLeone Feb 16, 2021
e4d5c9f
added a quad tree path - search not implemented.. not sure how.
DanielLeone Feb 17, 2021
ab88718
working on quadtree algorithm - looks promising
DanielLeone Feb 18, 2021
c7c2d1e
adding more detail to debug help - trying to reverse the transform
DanielLeone Feb 18, 2021
4a49d2e
more debugging - drawing quad tree levels is working - i think.
DanielLeone Feb 19, 2021
15c652c
more debugging ... more tests.
DanielLeone Feb 19, 2021
0fbb24c
* taking in skirt height - not using yet
DanielLeone Feb 19, 2021
03adf9b
flipping the Y direction (height - row) and that seems to fix it.... …
DanielLeone Feb 22, 2021
124262d
fixed the quadtree min/max heights
DanielLeone Feb 22, 2021
ab569b2
lots of changes
DanielLeone Feb 23, 2021
377f9dc
lots more changes - switched to using the terrain encoding object ins…
DanielLeone Feb 23, 2021
1228d6a
tighten up some coloring
DanielLeone Feb 24, 2021
9d303b4
reverted all the octree code
DanielLeone Feb 24, 2021
fef9e25
Merge remote-tracking branch 'upstream/master' into fastPicking2
DanielLeone Mar 2, 2021
a667116
yet more debugging stuff - and a x rotation on the transform
DanielLeone Mar 2, 2021
d506da6
and just like that, octree picking is back, kind of.
DanielLeone Apr 19, 2021
75ace54
more drawing of octree nodes, not drawing triangles for now
DanielLeone Apr 19, 2021
26cbe4e
man what a bug in that triangle packer! what an idiot! T_T
DanielLeone Apr 22, 2021
4853568
a few dev errors related to camera stuff... hmmm..... but actually so…
DanielLeone Apr 23, 2021
e195558
Merge remote-tracking branch 'upstream/master' into fastPickingWithOc…
DanielLeone Apr 24, 2021
853fe35
tracking of node intersections
DanielLeone Apr 24, 2021
6a85cd9
added octree back to heightmap terrain data.
DanielLeone Apr 27, 2021
d136d73
updated and merged in upstream - still seems to work after all this t…
DanielLeone Nov 19, 2021
52af827
* oh boy it's fast... finally made that optimization for caching the …
DanielLeone Nov 21, 2021
1bb353b
* fixed up some of the profiling scripts
DanielLeone Nov 24, 2021
fe06f25
* removed lots more unused code
DanielLeone Nov 24, 2021
1018d81
code cleanup, code removal, fixing some things in the terrain.html sa…
DanielLeone Nov 24, 2021
f236c15
removed a little more quadtree code
DanielLeone Nov 24, 2021
29ee6fa
trying to speed up creating packed triangles a bit
DanielLeone Nov 24, 2021
224836e
renamed TrianglePicking.js to OctreeTrianglePicking.js
DanielLeone Nov 24, 2021
8d427e1
code cleanup fixing up more of Terrain sandcastle
DanielLeone Nov 24, 2021
aa9dbe7
more cleanup
DanielLeone Nov 24, 2021
567a3c7
Merge remote-tracking branch 'upstream/main' into fastPickingWithOctree
DanielLeone Nov 25, 2021
f31dc77
made 2 new sandcastles and reverted the ones I hacked
DanielLeone Nov 25, 2021
5d2dce2
took some changes from upstream into the original globe pick function…
DanielLeone Nov 25, 2021
d78719e
removing unused code
DanielLeone Nov 27, 2021
de1d36c
added a dropdown to turn on/off default picking on the debug page
DanielLeone Nov 27, 2021
93a2487
checking frame state for exaggeration and scene mode to avoid the oct…
DanielLeone Nov 27, 2021
a470802
create trace dir if not exists
DanielLeone Dec 4, 2021
ea5bfcf
Merge remote-tracking branch 'upstream/main' into fastPickingWithOctree
DanielLeone Feb 4, 2022
9878687
change var to let/const now it's a real thing
DanielLeone Feb 4, 2022
b5c3d90
more of changing var to let/const
DanielLeone Feb 4, 2022
cd9ca23
Merge remote-tracking branch 'upstream/main' into fastPickingWithOctree
DanielLeone Apr 29, 2022
1d005a6
added exaggeration options to terrain debug sandcastle
DanielLeone Apr 29, 2022
a3b426d
removed duplicate method definition
DanielLeone Apr 29, 2022
26fe02d
passing in frameState parameter as required
DanielLeone Apr 30, 2022
358a793
fixed some eslint complaints
DanielLeone Apr 30, 2022
483ab35
FrameState is private, definitely breaking the public api here
DanielLeone Apr 30, 2022
526ea8e
fixing eslint errors
DanielLeone Apr 30, 2022
3111ef4
hide those private bits
DanielLeone Apr 30, 2022
3f69f5f
Okay, turns out that passing in mode as undefined was required for th…
DanielLeone May 6, 2022
8c48cb0
make getHeight pick in 3D mode
DanielLeone May 8, 2022
404b220
renamed a few things
DanielLeone May 16, 2022
f4e6772
no idea why this test failed, adding more logs
DanielLeone May 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Specs/jasmine/**
ThirdParty/**
Tools/**
Apps/Sandcastle/jsHintOptions.js
Apps/Sandcastle/fast-picking-analyze-results.js
Apps/Sandcastle/fast-picking-run-puppeteer.js
Apps/Sandcastle/gallery/gallery-index.js
index.html
index.release.html
index.release.html
3 changes: 0 additions & 3 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/jsLibraryMappings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

191 changes: 191 additions & 0 deletions Apps/Sandcastle/fast-picking-analyze-results.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import path from "path";
import fs from "fs";
const name = path.resolve(path.dirname(""));
const directoryPath = path.join(name, "Apps/Sandcastle/traces");

const methodNamesWeCareAbout = [
"nodeAddTriangle",
"getOverlap",
"TrianglePicking",
"computeVertices",
"createOctree",
];

const isLastOnlyArg = Array.from(process.argv).find((arg) =>
arg.toLowerCase().includes("--last")
);
const isIncludeLogsArg = Array.from(process.argv).find((arg) =>
arg.toLowerCase().includes("--logs")
);

const isLastOnly = !!isLastOnlyArg;
const isLastOnlyValue = isLastOnly
? isLastOnlyArg.replace("--last", "").replace("=", "").trim()
: undefined;
const lastCount = isLastOnlyValue ? parseInt(isLastOnlyValue) : 1;

const isIncludeLogs = !!isIncludeLogsArg;

fs.readdir(directoryPath, function (err, files) {
if (err) {
return console.log("Unable to scan directory: " + err);
}

let fileObjects = files
.filter((f) => f.endsWith(".json"))
.map((file) => {
const reg = new RegExp("(\\d+).json").exec(file);
const ts = parseInt(reg[1]);
return {
name: file,
ts,
};
});
let sortedFileObjects = fileObjects.sort((a, b) => a.ts - b.ts);

if (isLastOnly) {
sortedFileObjects = sortedFileObjects.slice(
sortedFileObjects.length - lastCount
);
}

sortedFileObjects.forEach(function (file) {
// Do whatever you want to do with the file
const timestamp = new Date(file.ts).toLocaleString();
let relevantLines = "";
var data = fs.readFileSync("Apps/Sandcastle/traces/" + file.name, "utf8");
let logs;
try {
logs = fs.readFileSync(
"Apps/Sandcastle/traces/" + file.name.replace(".json", ".txt"),
"utf8"
);
} catch (err) {}
if (logs) {
const logLines = logs
.split("\n")
.map((t) => t.trim())
.filter((t) => t.length > 2);
relevantLines = logLines
.filter((l) =>
methodNamesWeCareAbout.some((rel) =>
l.toLowerCase().includes(rel.toLowerCase())
)
)
.join("\n");
}
const obj = JSON.parse(data);

function ms(v) {
return Math.floor(v);
}

function maxMinAvg(arr) {
var max = arr[0];
var min = arr[0];
var sum = arr[0]; //changed from original post
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
sum = sum + arr[i];
}
return {
count: arr.length,
sum: ms(sum),
max: ms(max),
min: ms(min),
mean: ms(sum / arr.length),
}; //changed from original post
}

// {
// "args": {},
// "cat": "devtools.timeline,disabled-by-default-v8.gc",
// "dur": 3,
// "name": "V8.GC_STOP_THE_WORLD",
// "ph": "X",
// "pid": 43656,
// "tdur": 3,
// "tid": 76035,
// "ts": 151218196413,
// "tts": 14835
// }
//
// {
// "args": {},
// "cat": "devtools.timeline,disabled-by-default-v8.gc",
// "dur": 5,
// "name": "V8.GC_STOP_THE_WORLD",
// "ph": "X",
// "pid": 43656,
// "tdur": 4,
// "tid": 76035,
// "ts": 151218196701,
// "tts": 15123
// }
const measurements = {};

for (const event of obj.traceEvents) {
const isTimingEvent =
event.cat === "blink.console" &&
event.scope === "blink.console" &&
["b", "e"].includes(event.ph);
if (!isTimingEvent) {
continue;
}

const name = event.name;
if (!measurements[name]) {
measurements[name] = {
name: name,
samples: [],
begin: null,
};
}
const eventSamples = measurements[name];

const isBeginEvent = event.ph === "b";
const isEndEvent = event.ph === "e";

if (!isEndEvent && !isBeginEvent) {
throw new Error(`either begin or end event found: ${event}`);
}
if (isEndEvent && !eventSamples.begin) {
console.warn("end event before begin event");
continue;
}

if (isEndEvent) {
const endTimestamp = event.ts;
const beginTimestamp = eventSamples.begin;
const time = endTimestamp - beginTimestamp;
eventSamples.samples.push(time / 1000);
eventSamples.begin = null;
}

if (isBeginEvent) {
eventSamples.begin = event.ts;
}
}

const tableData = [];

for (const value of Object.values(measurements)) {
tableData.push({
event: value.name,
ts: timestamp,
...maxMinAvg(value.samples),
});
}
tableData.sort((a, b) => b.sum - a.sum);

console.table(tableData);
if (isIncludeLogs) {
console.log(relevantLines);
}
});
});
72 changes: 72 additions & 0 deletions Apps/Sandcastle/fast-picking-run-puppeteer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import puppeteer from "puppeteer";
import fs from "fs";
import shell from "shelljs";

const arcGISTerrainUrl =
"http://localhost:8080/Apps/Sandcastle/standalone.html#c=nVRtb9owEP4rFh8mqrVOQhKSMKjWN22V6F5UtGoS0mSSI1h1bGY70G7iv++SAIOWbtq+XXIvzz3PnW/BNFkqLbIRaM24JANyAYaXBU01MAt3O772z7EkRMP3Eoy9Q6e+Yea+R6wu4XjH9QW0hYcPShdMmK17dfRmLMdygYBMpzk366qftFrwDDQiS1hu0M90+u76dsQFZFcCFsxyJZ8ktCvIuiVCSi16jUXIuDWzdm56jgObTD+jDSZNVeE0pqOxVceAXvAUjFMT3UL5l84aDa3rguVwi4Ggx62a6Gosf7NZcFg+bf9L/a89bqX194WSFmvV+U3Ldp9L77Am+7LNmBmCzO3sHECe8xwhp6gw1AHTUqZV50SofI1+1EAZsCNegCptexu08RFSFdZQICiXeaW3IYONkg0zalKQQHOhJkC/mVJPWYqGxdihYtnnEkp4z/MZFXVz5PW/p99AVqn2/wWGarnOftMk8ylpP6F1SsIta3JIzGpR1+mrF6sMBgPiklevnhXYqZ2ptCxAWjpR2SNNBTNmyI2lLMtwJZZwwjScZErCuHW0D7gzvNqxOia+61b2qhryvhu34rlAINkEhcF5WOz5N6tqzpbpHOz+pl4wfKyGM+nX7wnRosiloRtHHT9O/DioFz7s+kHidajne34ShHFY/+0kUeyFHdqJu2EYhJ7Xbd5FhaWmU/MXLKwZ0CQK3CTuRnHY7dRFT6LEp37gJVESu7EXBV6DFSQJTbCvuOtGXd/rdtZYjQQpK0AzKpS6P7PthujxuomXwkaaSTPFM9Ve93fDrOYPAb2+vPowuh59bURuHbf6xj4KON3M9y0v5krb6uq0KXUsFHOB59A4kzK9B0tTYzZz7Tu7qf2MLwjPBgfuAqnXBD3TUohb/gN347TvYPyzVIFLj6P9iOdIsMcqbOadDpuflNK+g5+HM61SYsIQbMtkx9dcnhuQ5RPk3agfShXnpbVKmj9EZYCsxBAWIP4QZRjKBoer7dqof3XQ8Z4LlTIxU8b2cDNc52w+N84tk1nKjBXg5EwI0I/OLw";
const cesiumWorldTerrainUrl =
"http://localhost:8080/Apps/Sandcastle/standalone.html#c=nVRtb9owEP4rFh8mqrVOQhKSMKjWdtNWiXabilpNQppMcgSrjs1sB9pO/PddEqDQl03bt0vu5bnnufMtmCZLpUU2Aq0Zl2RAzsDwsqCpBmbhZsfX/jWWhGj4WYKxN+jUF8zc9ojVJRzuuK5BW7i7VLpgwmzdq4N3YzmWCwRkOs25WVf9qtWCZ6ARWcJyg36i00/nVyMuIPsoYMEsV/JJQruCrFsipNSi11iEjFsza+em5ziwyfQz2mDSVBVOYzoaW3UM6AVPwTg10S2U/8FZo6F1XrAcrjAQ9LhVE12N5SObBYfl0/av63/tcSutv8+UtFirzm9atvtcentD2FdrxswQZG5npwDylOeINEVhoQ6YljKtGiZC5WvQgwbBgB3xAlRp29ugjY+QqrCGAsG4zCuZDRlsBGwIUZOCBJoLNQH6w5R6ylI0LMYOFcu+lVDCZ57PqKibI2//Pf0Cskqs/y8wVMt19rsmmU9J+wmtYxJuWZOXxKz2c52+erXKYDAgLnnz5lmBndqZSssCpKUTld3TVDBjhtxYyrIMN2EJR0zDUaYkjFsH+4A7w6sdq0Piu25lr6oh77txK54LBJJNUBich8WeH1lVc7ZM52D3F/SM4Rs1nEm/fkaIFkUuDd046vhx4sdBvedh1w8Sr0M93/OTIIzD+m8niWIv7NBO3A3DIPS8bvMcKiw1nZq/YGHNgCZR4CZxN4rDbqcuehQlPvUDL4mS2I29KPAarCBJaIJ9xV036vpet7PGaiRIWQGaUaHU7YltN0QP1028FjbSTJopXqf2ur8LZjW/C+j5h4+Xo/PR90bk1mGrb+y9gOPNfN/zYq60rY5Nm1LHQjEXeAWNMynTW7A0NWYz176zm9rP+ILwbPDCOSD1mqBnWgpxxR9wN477DsY/SxW49DjaL3iFBLuvwmbe8bD5SSntO/j5cqZVSkwYgm2Z7Piai3MBsnyCvBv1oFRxWlqrpPlDVAbISgxhAeIPUYahbPBytV0b9a/uOJ5xoVImZsrYHm6G65zM58a5YjJLmbECnJwJAfre+Q0";

(async () => {
process.argv;
const now = Date.now();

let commit = shell.exec("git rev-parse --short HEAD");
commit = `${commit}`.trim();

if (!fs.existsSync("Apps/Sandcastle/traces/")) {
fs.mkdirSync("Apps/Sandcastle/traces/");
}
const path = `Apps/Sandcastle/traces/cesium_trace_${commit}__${now}.json`;
const logPath = `Apps/Sandcastle/traces/cesium_trace_${commit}__${now}.txt`;
const access = fs.createWriteStream(logPath);

var stdoutWrite = process.stdout.write;
var stderrWrite = process.stderr.write;

function write() {
stdoutWrite.apply(process.stdout, arguments);
access.write.apply(access, arguments);
}

function writeErr() {
stderrWrite.apply(process.stderr, arguments);
access.write.apply(access, arguments);
}

process.stdout.write = write;
process.stderr.write = writeErr;

const browser = await puppeteer.launch({
headless: false,
defaultViewport: false,
dumpio: true,
product: "chrome",
// product: "firefox",
args: [
`--window-size=${1800},${1800}`,
`--js-flags=--trace-opt --trace-deopt`,
],
});
let page;
try {
const url = arcGISTerrainUrl;
page = await browser.newPage();
await page.goto(url);

console.log(`starting trace ${path}`);
await page.tracing.start({ path, screenshots: false });
console.log("waiting for page to be ready");
await page.waitForFunction(
`document.body.classList.contains("we-are-done")`,
{ timeout: 60000 }
);
} finally {
if (page) {
console.log("stopping trace");
await page.tracing.stop();
}
console.log("closing browser");
await browser.close();
}
})();
Loading