feat:初始一次js文件格式化

main
陈炎群 5 months ago
parent f374f4c12c
commit d4602681c7

@ -1,39 +1,35 @@
import * as THREE from "./lib/three.module.js";
import { globalObjectCategory } from "./obj_cfg.js";
import { saveWorldList } from "./save.js";
import { intersect } from "./util.js";
function Annotation(sceneMeta, world, frameInfo) {
import * as THREE from './lib/three.module.js';
import {globalObjectCategory} from './obj_cfg.js';
import {saveWorldList} from "./save.js"
import { intersect } from './util.js';
function Annotation(sceneMeta, world, frameInfo){
this.world = world; this.world = world;
this.data = this.world.data; this.data = this.world.data;
//this.coordinatesOffset = this.world.coordinatesOffset; //this.coordinatesOffset = this.world.coordinatesOffset;
this.boxes_load_time = 0; this.boxes_load_time = 0;
this.frameInfo = frameInfo; this.frameInfo = frameInfo;
this.modified = false; this.modified = false;
this.setModified = function(){ this.setModified = function () {
this.modified=true; this.modified = true;
if (pointsGlobalConfig.autoSave) if (pointsGlobalConfig.autoSave) {
{
saveWorldList([this.world]); saveWorldList([this.world]);
} }
}; };
this.resetModified = function(){this.modified=false;}; this.resetModified = function () {
this.modified = false;
};
this.sort_boxes = function(){ this.sort_boxes = function () {
this.boxes = this.boxes.sort(function(x,y){ this.boxes = this.boxes.sort(function (x, y) {
return x.position.y - y.position.y; return x.position.y - y.position.y;
}); });
}; };
this.findBoxByTrackId = function(id){ this.findBoxByTrackId = function (id) {
if (this.boxes){ if (this.boxes) {
let box = this.boxes.find(function(x){ let box = this.boxes.find(function (x) {
return x.obj_track_id == id; return x.obj_track_id == id;
}); });
return box; return box;
@ -42,84 +38,77 @@ function Annotation(sceneMeta, world, frameInfo){
return null; return null;
}; };
this.findIntersectedBoxes = function(box){ this.findIntersectedBoxes = function (box) {
return this.boxes.filter(b=>b!=box).filter(b=>intersect(box, b)); return this.boxes.filter((b) => b != box).filter((b) => intersect(box, b));
}; };
this.preload = function(on_preload_finished){ this.preload = function (on_preload_finished) {
this.on_preload_finished = on_preload_finished; this.on_preload_finished = on_preload_finished;
this.load_annotation((boxes)=>this.proc_annotation(boxes)); this.load_annotation((boxes) => this.proc_annotation(boxes));
}; };
this.go_cmd_received = false; this.go_cmd_received = false;
this.webglScene = null; this.webglScene = null;
this.on_go_finished = null; this.on_go_finished = null;
this.go = function(webglScene, on_go_finished){ this.go = function (webglScene, on_go_finished) {
this.webglScene = webglScene; this.webglScene = webglScene;
if (this.preloaded){ if (this.preloaded) {
//this.boxes.forEach(b=>this.webglScene.add(b)); //this.boxes.forEach(b=>this.webglScene.add(b));
if (this.data.cfg.color_obj != "no"){ if (this.data.cfg.color_obj != "no") {
this.color_boxes(); this.color_boxes();
} }
if (on_go_finished) if (on_go_finished) on_go_finished();
on_go_finished();
} else { } else {
this.go_cmd_received = true; this.go_cmd_received = true;
this.on_go_finished = on_go_finished; this.on_go_finished = on_go_finished;
} }
}; };
// internal funcs below // internal funcs below
this._afterPreload = function(){ this._afterPreload = function () {
this.preloaded = true; this.preloaded = true;
console.log("annotation preloaded"); console.log("annotation preloaded");
if (this.on_preload_finished){ if (this.on_preload_finished) {
this.on_preload_finished(); this.on_preload_finished();
} }
if (this.go_cmd_received){ if (this.go_cmd_received) {
this.go(this.webglScene, this.on_go_finished); this.go(this.webglScene, this.on_go_finished);
} }
}; };
this.unload = function () {
this.unload = function(){ if (this.boxes) {
if (this.boxes){ this.boxes.forEach((b) => {
this.boxes.forEach((b)=>{
//this.webglGroup.remove(b); //this.webglGroup.remove(b);
if (b.boxEditor) if (b.boxEditor) b.boxEditor.detach();
b.boxEditor.detach();
}); });
} }
}; };
this.deleteAll = function(){ this.deleteAll = function () {
this.remove_all_boxes(); this.remove_all_boxes();
}; };
this.boxToAnn = function(box){ this.boxToAnn = function (box) {
let ann = { let ann = {
psr: { psr: {
position:{ position: {
x: box.position.x, x: box.position.x,
y: box.position.y, y: box.position.y,
z: box.position.z, z: box.position.z,
}, },
scale:{ scale: {
x: box.scale.x, x: box.scale.x,
y: box.scale.y, y: box.scale.y,
z: box.scale.z, z: box.scale.z,
}, },
rotation:{ rotation: {
x:box.rotation.x, x: box.rotation.x,
y:box.rotation.y, y: box.rotation.y,
z:box.rotation.z, z: box.rotation.z,
}, },
}, },
obj_type: box.obj_type, obj_type: box.obj_type,
@ -130,59 +119,59 @@ function Annotation(sceneMeta, world, frameInfo){
return ann; return ann;
}; };
this.toBoxAnnotations = function(){ this.toBoxAnnotations = function () {
let anns = this.boxes.map((b)=>{ let anns = this.boxes.map((b) => {
//var vertices = psr_to_xyz(b.position, b.scale, b.rotation); //var vertices = psr_to_xyz(b.position, b.scale, b.rotation);
let ann = this.boxToAnn(b); let ann = this.boxToAnn(b);
if (b.annotator) if (b.annotator) ann.annotator = b.annotator;
ann.annotator = b.annotator;
if (b.follows) if (b.follows) ann.follows = b.follows;
ann.follows = b.follows;
return ann; return ann;
}); });
anns.sort((a,b)=>a.obj_id- b.obj_id); anns.sort((a, b) => a.obj_id - b.obj_id);
return anns; return anns;
}; };
// to real-world position (no offset) // to real-world position (no offset)
this.ann_to_vector_global = function(box) { this.ann_to_vector_global = function (box) {
let posG = this.world.lidarPosToScene(box.position); let posG = this.world.lidarPosToScene(box.position);
let rotG = this.world.lidarRotToScene(box.rotation); let rotG = this.world.lidarRotToScene(box.rotation);
return [ return [
posG.x - this.world.coordinatesOffset[0], posG.y-this.world.coordinatesOffset[1], posG.z-this.world.coordinatesOffset[2], posG.x - this.world.coordinatesOffset[0],
rotG.x, rotG.y, rotG.z, posG.y - this.world.coordinatesOffset[1],
box.scale.x, box.scale.y, box.scale.z, posG.z - this.world.coordinatesOffset[2],
rotG.x,
rotG.y,
rotG.z,
box.scale.x,
box.scale.y,
box.scale.z,
]; ];
}; };
// real-world position to ann // real-world position to ann
this.vector_global_to_ann = function(v) this.vector_global_to_ann = function (v) {
{ let posG = new THREE.Vector3(
let posG = new THREE.Vector3(v[0]+this.world.coordinatesOffset[0], v[0] + this.world.coordinatesOffset[0],
v[1]+this.world.coordinatesOffset[1], v[1] + this.world.coordinatesOffset[1],
v[2]+this.world.coordinatesOffset[2]); v[2] + this.world.coordinatesOffset[2]
let rotG = new THREE.Euler(v[3],v[4],v[5]); );
let rotG = new THREE.Euler(v[3], v[4], v[5]);
let rotL = this.world.sceneRotToLidar(rotG); let rotL = this.world.sceneRotToLidar(rotG);
let posL = this.world.scenePosToLidar(posG); let posL = this.world.scenePosToLidar(posG);
return { return {
position: {x: posL.x, y: posL.y, z: posL.z}, position: { x: posL.x, y: posL.y, z: posL.z },
rotation: {x: rotL.x, y: rotL.y, z: rotL.z}, rotation: { x: rotL.x, y: rotL.y, z: rotL.z },
scale: {x: v[6], y: v[7], z: v[8]} scale: { x: v[6], y: v[7], z: v[8] },
}; };
}; };
// this.vector_to_ann = function(v){ // this.vector_to_ann = function(v){
// return { // return {
// position:{ // position:{
@ -191,7 +180,6 @@ function Annotation(sceneMeta, world, frameInfo){
// z:v[2],// + this.coordinatesOffset[2], // z:v[2],// + this.coordinatesOffset[2],
// }, // },
// rotation:{ // rotation:{
// x:v[3], // x:v[3],
// y:v[4], // y:v[4],
@ -207,9 +195,9 @@ function Annotation(sceneMeta, world, frameInfo){
// }; // };
// }; // };
this.remove_all_boxes = function(){ this.remove_all_boxes = function () {
if (this.boxes){ if (this.boxes) {
this.boxes.forEach((b)=>{ this.boxes.forEach((b) => {
this.webglGroup.remove(b); this.webglGroup.remove(b);
this.world.data.dbg.free(); this.world.data.dbg.free();
b.geometry.dispose(); b.geometry.dispose();
@ -219,37 +207,100 @@ function Annotation(sceneMeta, world, frameInfo){
}); });
this.boxes = []; this.boxes = [];
} } else {
else{ console.error("destroy empty world!");
console.error("destroy empty world!")
} }
}; };
this.new_bbox_cube=function(color){ this.new_bbox_cube = function (color) {
var h = 0.5; var h = 0.5;
var body = [ var body = [
//top //top
-h,h,h, h,h,h, -h,
h,h,h, h,-h,h, h,
h,-h,h, -h,-h,h, h,
-h,-h,h, -h, h, h, h,
h,
h,
h,
h,
h,
h,
-h,
h,
h,
-h,
h,
-h,
-h,
h,
-h,
-h,
h,
-h,
h,
h,
//botom //botom
-h,h,-h, h,h,-h, -h,
h,h,-h, h,-h,-h, h,
h,-h,-h, -h,-h,-h, -h,
-h,-h,-h, -h, h, -h, h,
h,
-h,
h,
h,
-h,
h,
-h,
-h,
h,
-h,
-h,
-h,
-h,
-h,
-h,
-h,
-h,
-h,
h,
-h,
// vertical lines // vertical lines
-h,h,h, -h,h,-h, -h,
h,h,h, h,h,-h, h,
h,-h,h, h,-h,-h, h,
-h,-h,h, -h,-h,-h, -h,
h,
-h,
h,
h,
h,
h,
h,
-h,
h,
-h,
h,
h,
-h,
-h,
-h,
-h,
h,
-h,
-h,
-h,
//direction //direction
h, 0, h, 1.5*h, 0, h, h,
0,
h,
1.5 * h,
0,
h,
//h/2, -h, h+0.1, h, 0, h+0.1, //h/2, -h, h+0.1, h, 0, h+0.1,
//h/2, h, h+0.1, h, 0, h+0.1, //h/2, h, h+0.1, h, 0, h+0.1,
@ -257,16 +308,14 @@ function Annotation(sceneMeta, world, frameInfo){
// h, h/2, h, h, h, 0, // h, h/2, h, h, h, 0,
// h, h/2, -h, h, h, 0, // h, h/2, -h, h, h, 0,
// h, 0, 0, h, h, 0, // h, 0, 0, h, h, 0,
]; ];
this.world.data.dbg.alloc(); this.world.data.dbg.alloc();
var bbox = new THREE.BufferGeometry(); var bbox = new THREE.BufferGeometry();
bbox.setAttribute( 'position', new THREE.Float32BufferAttribute(body, 3 ) ); bbox.setAttribute("position", new THREE.Float32BufferAttribute(body, 3));
if (!color){ if (!color) {
color = 0x00ff00; color = 0x00ff00;
} }
@ -275,25 +324,38 @@ function Annotation(sceneMeta, world, frameInfo){
linewidth is 1, regardless of set value. linewidth is 1, regardless of set value.
*/ */
var material = new THREE.LineBasicMaterial({
color: color,
linewidth: 1,
opacity: this.data.cfg.box_opacity,
transparent: true,
});
var box = new THREE.LineSegments(bbox, material);
var material = new THREE.LineBasicMaterial( { color: color, linewidth: 1, opacity: this.data.cfg.box_opacity, transparent: true } ); box.scale.x = 1.8;
var box = new THREE.LineSegments( bbox, material ); box.scale.y = 4.5;
box.scale.z = 1.5;
box.scale.x=1.8; box.name = "bbox";
box.scale.y=4.5; box.obj_type = "car";
box.scale.z=1.5;
box.name="bbox";
box.obj_type="car";
//box.computeLineDistances(); //box.computeLineDistances();
return box; return box;
}; };
this.createCuboid = function(pos, scale, rotation, obj_type, track_id, obj_attr){ this.createCuboid = function (
let mesh = this.new_bbox_cube(parseInt("0x"+globalObjectCategory.get_obj_cfg_by_type(obj_type).color.slice(1))); pos,
scale,
rotation,
obj_type,
track_id,
obj_attr
) {
let mesh = this.new_bbox_cube(
parseInt(
"0x" + globalObjectCategory.get_obj_cfg_by_type(obj_type).color.slice(1)
)
);
mesh.position.x = pos.x; mesh.position.x = pos.x;
mesh.position.y = pos.y; mesh.position.y = pos.y;
mesh.position.z = pos.z; mesh.position.z = pos.z;
@ -319,9 +381,15 @@ function Annotation(sceneMeta, world, frameInfo){
pos: offset position, after transformed pos: offset position, after transformed
*/ */
this.add_box=function(pos, scale, rotation, obj_type, track_id, obj_attr){ this.add_box = function (pos, scale, rotation, obj_type, track_id, obj_attr) {
let mesh = this.createCuboid(
let mesh = this.createCuboid(pos, scale, rotation, obj_type, track_id, obj_attr) pos,
scale,
rotation,
obj_type,
track_id,
obj_attr
);
this.boxes.push(mesh); this.boxes.push(mesh);
this.sort_boxes(); this.sort_boxes();
@ -331,78 +399,71 @@ function Annotation(sceneMeta, world, frameInfo){
return mesh; return mesh;
}; };
this.load_box = function(box){ this.load_box = function (box) {
this.webglGroup.add(box); this.webglGroup.add(box);
}; };
this.unload_box = function(box){ this.unload_box = function (box) {
this.webglGroup.remove(box); this.webglGroup.remove(box);
}; };
this.remove_box=function(box){ this.remove_box = function (box) {
this.world.data.dbg.free(); this.world.data.dbg.free();
box.geometry.dispose(); box.geometry.dispose();
box.material.dispose(); box.material.dispose();
//selected_box.dispose(); //selected_box.dispose();
this.boxes = this.boxes.filter(function(x){return x !=box;}); this.boxes = this.boxes.filter(function (x) {
return x != box;
});
}; };
this.set_box_opacity=function(box_opacity){ this.set_box_opacity = function (box_opacity) {
this.boxes.forEach(function(x){ this.boxes.forEach(function (x) {
x.material.opacity = box_opacity; x.material.opacity = box_opacity;
}); });
}; };
this.translate_box_position=function(pos, theta, axis, delta){ this.translate_box_position = function (pos, theta, axis, delta) {
switch (axis){ switch (axis) {
case 'x': case "x":
pos.x += delta*Math.cos(theta); pos.x += delta * Math.cos(theta);
pos.y += delta*Math.sin(theta); pos.y += delta * Math.sin(theta);
break; break;
case 'y': case "y":
pos.x += delta*Math.cos(Math.PI/2 + theta); pos.x += delta * Math.cos(Math.PI / 2 + theta);
pos.y += delta*Math.sin(Math.PI/2 + theta); pos.y += delta * Math.sin(Math.PI / 2 + theta);
break; break;
case 'z': case "z":
pos.z += delta; pos.z += delta;
break; break;
} }
}; };
this.find_boxes_inside_rect = function(x,y,w,h, camera){ (this.find_boxes_inside_rect = function (x, y, w, h, camera) {
let selected_boxes_by_rect = []; let selected_boxes_by_rect = [];
if (!this.boxes) if (!this.boxes) return selected_boxes_by_rect;
return selected_boxes_by_rect;
var p = new THREE.Vector3(); var p = new THREE.Vector3();
for (var i=0; i< this.boxes.length; i++){ for (var i = 0; i < this.boxes.length; i++) {
let box_center = this.boxes[i].position; let box_center = this.boxes[i].position;
let pw = this.world.lidarPosToScene(box_center); let pw = this.world.lidarPosToScene(box_center);
p.set(pw.x, pw.y, pw.z); p.set(pw.x, pw.y, pw.z);
p.project(camera); p.project(camera);
p.x = p.x/p.z; p.x = p.x / p.z;
p.y = p.y/p.z; p.y = p.y / p.z;
//console.log(p); //console.log(p);
if ((p.x > x) && (p.x < x+w) && (p.y>y) && (p.y<y+h)){ if (p.x > x && p.x < x + w && p.y > y && p.y < y + h) {
selected_boxes_by_rect.push(this.boxes[i]); selected_boxes_by_rect.push(this.boxes[i]);
} }
} }
console.log("select boxes", selected_boxes_by_rect.length); console.log("select boxes", selected_boxes_by_rect.length);
return selected_boxes_by_rect; return selected_boxes_by_rect;
}, }),
(this.proc_annotation = function (boxes) {
this.proc_annotation = function(boxes){
// boxes = this.transformBoxesByEgoPose(boxes); // boxes = this.transformBoxesByEgoPose(boxes);
// boxes = this.transformBoxesByOffset(boxes); // boxes = this.transformBoxesByOffset(boxes);
@ -412,22 +473,29 @@ function Annotation(sceneMeta, world, frameInfo){
this.webglGroup = new THREE.Group(); this.webglGroup = new THREE.Group();
this.webglGroup.name = "annotations"; this.webglGroup.name = "annotations";
this.boxes.forEach(b=>this.webglGroup.add(b)); this.boxes.forEach((b) => this.webglGroup.add(b));
this.world.webglGroup.add(this.webglGroup); this.world.webglGroup.add(this.webglGroup);
this.boxes_load_time = new Date().getTime(); this.boxes_load_time = new Date().getTime();
console.log(this.boxes_load_time, this.frameInfo.scene, this.frameInfo.frame, "loaded boxes ", this.boxes_load_time - this.create_time, "ms"); console.log(
this.boxes_load_time,
this.frameInfo.scene,
this.frameInfo.frame,
"loaded boxes ",
this.boxes_load_time - this.create_time,
"ms"
);
this.sort_boxes(); this.sort_boxes();
this._afterPreload(); this._afterPreload();
}; });
this.load_annotation=function(on_load){ this.load_annotation = function (on_load) {
if (this.data.cfg.disableLabels){ if (this.data.cfg.disableLabels) {
on_load([]); on_load([]);
}else { } else {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
// we defined the xhr // we defined the xhr
var _self = this; var _self = this;
@ -442,67 +510,87 @@ function Annotation(sceneMeta, world, frameInfo){
// end of state change: it can be after some time (async) // end of state change: it can be after some time (async)
}; };
xhr.open('GET', "/load_annotation"+"?scene="+this.frameInfo.scene+"&frame="+this.frameInfo.frame, true); xhr.open(
"GET",
"/load_annotation" +
"?scene=" +
this.frameInfo.scene +
"&frame=" +
this.frameInfo.frame,
true
);
xhr.send(); xhr.send();
} }
}; };
this.reloadAnnotation=function(done){ this.reloadAnnotation = function (done) {
this.load_annotation(ann=>{ this.load_annotation((ann) => {
this.reapplyAnnotation(ann, done); this.reapplyAnnotation(ann, done);
}); });
}; };
this.reapplyAnnotation = function (boxes, done) {
this.reapplyAnnotation = function(boxes, done){
// these boxes haven't attached a world // these boxes haven't attached a world
//boxes = this.transformBoxesByOffset(boxes); //boxes = this.transformBoxesByOffset(boxes);
// mark all old boxes // mark all old boxes
this.boxes.forEach(b=>{b.delete=true;}); this.boxes.forEach((b) => {
b.delete = true;
let pendingBoxList=[]; });
boxes.forEach(nb=>{ // nb is annotation format, not a true box let pendingBoxList = [];
let old_box = this.boxes.find(function(x){
return x.obj_track_id == nb.obj_id && x.obj_track_id != "" && nb.obj_id != "" && x.obj_type == nb.obj_type;; boxes.forEach((nb) => {
// nb is annotation format, not a true box
let old_box = this.boxes.find(function (x) {
return (
x.obj_track_id == nb.obj_id &&
x.obj_track_id != "" &&
nb.obj_id != "" &&
x.obj_type == nb.obj_type
);
}); });
if (old_box){ if (old_box) {
// found // found
// update psr // update psr
delete old_box.delete; // unmark delete flag delete old_box.delete; // unmark delete flag
old_box.position.set(nb.psr.position.x, nb.psr.position.y, nb.psr.position.z); old_box.position.set(
nb.psr.position.x,
nb.psr.position.y,
nb.psr.position.z
);
old_box.scale.set(nb.psr.scale.x, nb.psr.scale.y, nb.psr.scale.z); old_box.scale.set(nb.psr.scale.x, nb.psr.scale.y, nb.psr.scale.z);
old_box.rotation.set(nb.psr.rotation.x, nb.psr.rotation.y, nb.psr.rotation.z); old_box.rotation.set(
nb.psr.rotation.x,
nb.psr.rotation.y,
nb.psr.rotation.z
);
old_box.obj_attr = nb.obj_attr; old_box.obj_attr = nb.obj_attr;
old_box.annotator = nb.annotator; old_box.annotator = nb.annotator;
old_box.changed=false; // clear changed flag. old_box.changed = false; // clear changed flag.
} else {
}else{
// not found // not found
let box=this.createOneBoxByAnn(nb); let box = this.createOneBoxByAnn(nb);
pendingBoxList.push(box); pendingBoxList.push(box);
} }
}); });
// delete removed // delete removed
let toBeDelBoxes = this.boxes.filter(b=>b.delete); let toBeDelBoxes = this.boxes.filter((b) => b.delete);
toBeDelBoxes.forEach(b=>{ toBeDelBoxes.forEach((b) => {
if (b.boxEditor){ if (b.boxEditor) {
b.boxEditor.detach("donthide"); b.boxEditor.detach("donthide");
} }
this.webglGroup.remove(b); this.webglGroup.remove(b);
this.remove_box(b); this.remove_box(b);
}) });
pendingBoxList.forEach(b=>{ pendingBoxList.forEach((b) => {
this.boxes.push(b); this.boxes.push(b);
}) });
//todo, restore point color //todo, restore point color
//todo, update imagecontext, selected box, ... //todo, update imagecontext, selected box, ...
@ -513,79 +601,71 @@ function Annotation(sceneMeta, world, frameInfo){
this.color_boxes(); this.color_boxes();
// add new boxes // add new boxes
pendingBoxList.forEach(b=>{ pendingBoxList.forEach((b) => {
this.webglGroup.add(b); this.webglGroup.add(b);
}) });
this.resetModified(); this.resetModified();
if (done) if (done) done();
done(); };
}
this.createOneBoxByAnn = function(annotation){ this.createOneBoxByAnn = function (annotation) {
let b = annotation; let b = annotation;
let mesh = this.createCuboid(b.psr.position, let mesh = this.createCuboid(
b.psr.position,
b.psr.scale, b.psr.scale,
b.psr.rotation, b.psr.rotation,
b.obj_type, b.obj_type,
b.obj_id, b.obj_id,
b.obj_attr); b.obj_attr
);
if (b.annotator){ if (b.annotator) {
mesh.annotator = b.annotator; mesh.annotator = b.annotator;
} }
if (b.follows) if (b.follows) mesh.follows = b.follows;
mesh.follows = b.follows;
return mesh; return mesh;
}; };
this.createBoxes = function(annotations){ this.createBoxes = function (annotations) {
return annotations.map((b)=>{ return annotations.map((b) => {
return this.createOneBoxByAnn(b); return this.createOneBoxByAnn(b);
}); });
}; };
this.box_local_id = 0; this.box_local_id = 0;
this.get_new_box_local_id=function(){ this.get_new_box_local_id = function () {
var ret = this.box_local_id; var ret = this.box_local_id;
this.box_local_id+=1; this.box_local_id += 1;
return ret; return ret;
}; };
this.color_box = function (box) {
this.color_box = function(box) if (
{ this.data.cfg.color_obj == "category" ||
if (this.data.cfg.color_obj == "category" || this.data.cfg.color_obj == "no") this.data.cfg.color_obj == "no"
{ ) {
let color = globalObjectCategory.get_color_by_category(box.obj_type); let color = globalObjectCategory.get_color_by_category(box.obj_type);
box.material.color.r=color.x; box.material.color.r = color.x;
box.material.color.g=color.y; box.material.color.g = color.y;
box.material.color.b=color.z; box.material.color.b = color.z;
} } else {
else
{
let color = globalObjectCategory.get_color_by_id(box.obj_track_id); let color = globalObjectCategory.get_color_by_id(box.obj_track_id);
box.material.color.r=color.x; box.material.color.r = color.x;
box.material.color.g=color.y; box.material.color.g = color.y;
box.material.color.b=color.z; box.material.color.b = color.z;
}
} }
};
this.color_boxes = function() this.color_boxes = function () {
{ this.boxes.forEach((box) => {
this.boxes.forEach(box=>{
this.color_box(box); this.color_box(box);
}) });
} };
} }
export { Annotation };
export{Annotation}

@ -1,23 +1,26 @@
import {
import {transpose, matmul2, euler_angle_to_rotate_matrix_3by3,normalizeAngle } from "./util.js"; transpose,
matmul2,
euler_angle_to_rotate_matrix_3by3,
normalizeAngle,
} from "./util.js";
import { logger } from "./log.js"; import { logger } from "./log.js";
// todo: this module needs a proper name // todo: this module needs a proper name
function AutoAdjust(boxOp, mouse, header){ function AutoAdjust(boxOp, mouse, header) {
this.boxOp = boxOp, (this.boxOp = boxOp), (this.mouse = mouse);
this.mouse = mouse;
this.header = header; this.header = header;
var marked_object = null; var marked_object = null;
// mark bbox, which will be used as reference-bbox of an object. // mark bbox, which will be used as reference-bbox of an object.
this.mark_bbox=function(box){ this.mark_bbox = function (box) {
if (box){ if (box) {
this.marked_object = { this.marked_object = {
frame: box.world.frameInfo.frame, frame: box.world.frameInfo.frame,
scene: box.world.frameInfo.scene, scene: box.world.frameInfo.scene,
ann: box.world.annotation.boxToAnn(box), ann: box.world.annotation.boxToAnn(box),
} };
logger.log(`selected reference objcet ${this.marked_object}`); logger.log(`selected reference objcet ${this.marked_object}`);
@ -25,16 +28,18 @@ function AutoAdjust(boxOp, mouse, header){
} }
}; };
this.followStaticObjects = function(box) { this.followStaticObjects = function (box) {
let world = box.world; let world = box.world;
let staticObjects = world.annotation.boxes. let staticObjects = world.annotation.boxes
filter(b=>b!=box && b.obj_attr && b.obj_attr.search('static')>=0). .filter((b) => b != box && b.obj_attr && b.obj_attr.search("static") >= 0)
map(refObj=>{ .map((refObj) => {
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation); let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
let trans = transpose(coord, 3); let trans = transpose(coord, 3);
let p = [box.position.x - refObj.position.x, let p = [
box.position.x - refObj.position.x,
box.position.y - refObj.position.y, box.position.y - refObj.position.y,
box.position.z - refObj.position.z]; box.position.z - refObj.position.z,
];
let relativePos = matmul2(trans, p, 3); let relativePos = matmul2(trans, p, 3);
let relativeRot = { let relativeRot = {
x: normalizeAngle(box.rotation.x - refObj.rotation.x), x: normalizeAngle(box.rotation.x - refObj.rotation.x),
@ -42,37 +47,41 @@ function AutoAdjust(boxOp, mouse, header){
z: normalizeAngle(box.rotation.z - refObj.rotation.z), z: normalizeAngle(box.rotation.z - refObj.rotation.z),
}; };
let distance = Math.sqrt(
let distance = Math.sqrt(relativePos[0]*relativePos[0] + relativePos[1]*relativePos[1] + relativePos[2]*relativePos[2]); relativePos[0] * relativePos[0] +
relativePos[1] * relativePos[1] +
relativePos[2] * relativePos[2]
);
return { return {
obj_track_id: refObj.obj_track_id, obj_track_id: refObj.obj_track_id,
relativePos, relativePos,
relativeRot, relativeRot,
distance distance,
};
}
}); });
let worldList = box.world.data.worldList; let worldList = box.world.data.worldList;
//let saveList = []; //let saveList = [];
worldList.forEach(w=>{ worldList.forEach((w) => {
if (w === box.world){ if (w === box.world) {
//current frame //current frame
return; return;
} }
let existedBox = w.annotation.boxes.find(b=>b.obj_track_id == box.obj_track_id); let existedBox = w.annotation.boxes.find(
if (existedBox && !existedBox.annotator) (b) => b.obj_track_id == box.obj_track_id
{ );
if (existedBox && !existedBox.annotator) {
// have same objects annotated. // have same objects annotated.
// if its generated by machine, lets overwrite it // if its generated by machine, lets overwrite it
return; return;
} }
let candPoseSets = staticObjects.map(refObj=>{ let candPoseSets = staticObjects.map((refObj) => {
let refObjInW = w.annotation.boxes.find(
let refObjInW = w.annotation.boxes.find(b=>b.obj_track_id == refObj.obj_track_id); (b) => b.obj_track_id == refObj.obj_track_id
if (!refObjInW){ );
if (!refObjInW) {
// not found refobj in this world, give up // not found refobj in this world, give up
return null; return null;
} }
@ -92,32 +101,29 @@ function AutoAdjust(boxOp, mouse, header){
let newObjRot = { let newObjRot = {
x: normalizeAngle(refObjInW.rotation.x + relativeRot.x), x: normalizeAngle(refObjInW.rotation.x + relativeRot.x),
y: normalizeAngle(refObjInW.rotation.y + relativeRot.y), y: normalizeAngle(refObjInW.rotation.y + relativeRot.y),
z: normalizeAngle(refObjInW.rotation.z + relativeRot.z) z: normalizeAngle(refObjInW.rotation.z + relativeRot.z),
}; };
return { return {
distance: refObj.distance, distance: refObj.distance,
weight: Math.exp(-refObj.distance * (refObjInW.annotator?1:0.1)), weight: Math.exp(-refObj.distance * (refObjInW.annotator ? 1 : 0.1)),
position: newObjPos, position: newObjPos,
rotation: newObjRot, rotation: newObjRot,
}; };
}); });
candPoseSets = candPoseSets.filter(p=>!!p); candPoseSets = candPoseSets.filter((p) => !!p);
if (candPoseSets.length == 0) { if (candPoseSets.length == 0) {
return; return;
} }
// calculate mean pos/rot // calculate mean pos/rot
let denorm = candPoseSets.reduce((a,b)=>a+b.weight, 0); let denorm = candPoseSets.reduce((a, b) => a + b.weight, 0);
let newObjPos = {x:0, y:0, z:0}; let newObjPos = { x: 0, y: 0, z: 0 };
let newObjRot = {x:0, y:0, z:0, cosZ: 0, sinZ:0}; let newObjRot = { x: 0, y: 0, z: 0, cosZ: 0, sinZ: 0 };
candPoseSets.forEach(p=>{ candPoseSets.forEach((p) => {
newObjPos.x += p.position.x * p.weight; newObjPos.x += p.position.x * p.weight;
newObjPos.y += p.position.y * p.weight; newObjPos.y += p.position.y * p.weight;
newObjPos.z += p.position.z * p.weight; newObjPos.z += p.position.z * p.weight;
@ -138,20 +144,22 @@ function AutoAdjust(boxOp, mouse, header){
newObjRot.sinZ /= denorm; newObjRot.sinZ /= denorm;
newObjRot.z = Math.atan2(newObjRot.sinZ, newObjRot.cosZ); newObjRot.z = Math.atan2(newObjRot.sinZ, newObjRot.cosZ);
// ignor distant objects // ignor distant objects
if (pointsGlobalConfig.ignoreDistantObject){ if (pointsGlobalConfig.ignoreDistantObject) {
let objDistance = Math.sqrt(newObjPos.x * newObjPos.x + newObjPos.y * newObjPos.y + newObjPos.z * newObjPos.z); let objDistance = Math.sqrt(
newObjPos.x * newObjPos.x +
newObjPos.y * newObjPos.y +
newObjPos.z * newObjPos.z
);
if ((box.scale.z < 2 && objDistance > 100) || objDistance > 150) if ((box.scale.z < 2 && objDistance > 100) || objDistance > 150) {
{
return; return;
} }
} }
// apply // apply
if (existedBox){ if (existedBox) {
existedBox.position.x = newObjPos.x; existedBox.position.x = newObjPos.x;
existedBox.position.y = newObjPos.y; existedBox.position.y = newObjPos.y;
existedBox.position.z = newObjPos.z; existedBox.position.z = newObjPos.z;
@ -164,18 +172,19 @@ function AutoAdjust(boxOp, mouse, header){
existedBox.scale.y = box.scale.y; existedBox.scale.y = box.scale.y;
existedBox.scale.z = box.scale.z; existedBox.scale.z = box.scale.z;
existedBox.annotator="S"; existedBox.annotator = "S";
logger.log(`modified box in ${w}`); logger.log(`modified box in ${w}`);
} else{ } else {
let newBox = w.annotation.add_box(newObjPos, let newBox = w.annotation.add_box(
newObjPos,
box.scale, box.scale,
newObjRot, newObjRot,
box.obj_type, box.obj_type,
box.obj_track_id, box.obj_track_id,
box.obj_attr); box.obj_attr
newBox.annotator="S"; );
newBox.annotator = "S";
w.annotation.load_box(newBox); w.annotation.load_box(newBox);
logger.log(`inserted box in ${w}`); logger.log(`inserted box in ${w}`);
@ -184,28 +193,29 @@ function AutoAdjust(boxOp, mouse, header){
console.log("added box in ", w.frameInfo.frame); console.log("added box in ", w.frameInfo.frame);
//saveList.push(w); //saveList.push(w);
w.annotation.setModified(); w.annotation.setModified();
}); });
}; };
this.followsRef = function(box){ this.followsRef = function (box) {
//find ref object in current frame //find ref object in current frame
let world = box.world; let world = box.world;
let refObj = world.annotation.boxes.find(b=>b.obj_track_id == this.marked_object.ann.obj_id); let refObj = world.annotation.boxes.find(
if (refObj){ (b) => b.obj_track_id == this.marked_object.ann.obj_id
);
if (refObj) {
console.log("found ref obj in current frame"); console.log("found ref obj in current frame");
world.annotation.setModified() world.annotation.setModified();
//compute relative position //compute relative position
// represent obj in coordinate system of refobj // represent obj in coordinate system of refobj
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation); let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
let trans = transpose(coord, 3); let trans = transpose(coord, 3);
let p = [box.position.x - refObj.position.x, let p = [
box.position.x - refObj.position.x,
box.position.y - refObj.position.y, box.position.y - refObj.position.y,
box.position.z - refObj.position.z]; box.position.z - refObj.position.z,
];
const relativePos = matmul2(trans, p, 3); const relativePos = matmul2(trans, p, 3);
const relativeRot = { const relativeRot = {
x: box.rotation.x - refObj.rotation.x, x: box.rotation.x - refObj.rotation.x,
@ -215,23 +225,26 @@ function AutoAdjust(boxOp, mouse, header){
let worldList = box.world.data.worldList; let worldList = box.world.data.worldList;
//let saveList = []; //let saveList = [];
worldList.forEach(w=>{ worldList.forEach((w) => {
if (w === box.world){ if (w === box.world) {
//current frame //current frame
return; return;
} }
let existedBox = w.annotation.boxes.find(b=>b.obj_track_id == box.obj_track_id); let existedBox = w.annotation.boxes.find(
(b) => b.obj_track_id == box.obj_track_id
);
if (existedBox && !existedBox.annotator) if (existedBox && !existedBox.annotator) {
{
// have same objects annotated. // have same objects annotated.
// if its generated by machine, lets overwrite it // if its generated by machine, lets overwrite it
return; return;
} }
let refObjInW = w.annotation.boxes.find(b=>b.obj_track_id == refObj.obj_track_id); let refObjInW = w.annotation.boxes.find(
if (!refObjInW){ (b) => b.obj_track_id == refObj.obj_track_id
);
if (!refObjInW) {
// not found refobj in this world, give up // not found refobj in this world, give up
return; return;
} }
@ -248,10 +261,10 @@ function AutoAdjust(boxOp, mouse, header){
let newObjRot = { let newObjRot = {
x: refObjInW.rotation.x + relativeRot.x, x: refObjInW.rotation.x + relativeRot.x,
y: refObjInW.rotation.y + relativeRot.y, y: refObjInW.rotation.y + relativeRot.y,
z: refObjInW.rotation.z + relativeRot.z z: refObjInW.rotation.z + relativeRot.z,
}; };
if (existedBox){ if (existedBox) {
existedBox.position.x = newObjPos.x; existedBox.position.x = newObjPos.x;
existedBox.position.y = newObjPos.y; existedBox.position.y = newObjPos.y;
existedBox.position.z = newObjPos.z; existedBox.position.z = newObjPos.z;
@ -264,7 +277,7 @@ function AutoAdjust(boxOp, mouse, header){
existedBox.scale.y = box.scale.y; existedBox.scale.y = box.scale.y;
existedBox.scale.z = box.scale.z; existedBox.scale.z = box.scale.z;
existedBox.annotator="F"; existedBox.annotator = "F";
existedBox.follows = { existedBox.follows = {
obj_track_id: refObj.obj_track_id, obj_track_id: refObj.obj_track_id,
relative_position: { relative_position: {
@ -276,14 +289,16 @@ function AutoAdjust(boxOp, mouse, header){
}; };
logger.log(`modified box in ${w}`); logger.log(`modified box in ${w}`);
} else{ } else {
let newBox = w.annotation.add_box(newObjPos, let newBox = w.annotation.add_box(
newObjPos,
box.scale, box.scale,
newObjRot, newObjRot,
box.obj_type, box.obj_type,
box.obj_track_id, box.obj_track_id,
box.obj_attr); box.obj_attr
newBox.annotator="F"; );
newBox.annotator = "F";
newBox.follows = { newBox.follows = {
obj_track_id: refObj.obj_track_id, obj_track_id: refObj.obj_track_id,
relative_position: { relative_position: {
@ -307,11 +322,13 @@ function AutoAdjust(boxOp, mouse, header){
} }
}; };
this.syncFollowers = function(box){ this.syncFollowers = function (box) {
let world = box.world; let world = box.world;
let allFollowers = world.annotation.boxes.filter(b=>b.follows && b.follows.obj_track_id === box.obj_track_id); let allFollowers = world.annotation.boxes.filter(
(b) => b.follows && b.follows.obj_track_id === box.obj_track_id
);
if (allFollowers.length == 0){ if (allFollowers.length == 0) {
console.log("no followers"); console.log("no followers");
return; return;
} }
@ -319,9 +336,9 @@ function AutoAdjust(boxOp, mouse, header){
let refObj = box; let refObj = box;
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation); let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
allFollowers.forEach((fb) => {
allFollowers.forEach(fb=>{ let relpos = [
let relpos = [fb.follows.relative_position.x, fb.follows.relative_position.x,
fb.follows.relative_position.y, fb.follows.relative_position.y,
fb.follows.relative_position.z, fb.follows.relative_position.z,
]; ];
@ -338,18 +355,20 @@ function AutoAdjust(boxOp, mouse, header){
}); });
}; };
this.paste_bbox=function(pos, add_box){ this.paste_bbox = function (pos, add_box) {
if (!pos) pos = this.marked_object.ann.psr.position;
if (!pos) else pos.z = this.marked_object.ann.psr.position.z;
pos = this.marked_object.ann.psr.position;
else return add_box(
pos.z = this.marked_object.ann.psr.position.z; pos,
this.marked_object.ann.psr.scale,
return add_box(pos, this.marked_object.ann.psr.scale, this.marked_object.ann.psr.rotation, this.marked_object.ann.psr.rotation,
this.marked_object.ann.obj_type, this.marked_object.ann.obj_id, this.marked_object.ann.obj_attr); this.marked_object.ann.obj_type,
this.marked_object.ann.obj_id,
this.marked_object.ann.obj_attr
);
}; };
// this.auto_adjust_bbox=function(box, done, on_box_changed){ // this.auto_adjust_bbox=function(box, done, on_box_changed){
// saveWorld(function(){ // saveWorld(function(){
@ -370,7 +389,6 @@ function AutoAdjust(boxOp, mouse, header){
// console.log(box.position); // console.log(box.position);
// console.log(box.rotation); // console.log(box.rotation);
// var trans_mat = JSON.parse(this.responseText); // var trans_mat = JSON.parse(this.responseText);
// var rotation = Math.atan2(trans_mat[4], trans_mat[0]) + box.rotation.z; // var rotation = Math.atan2(trans_mat[4], trans_mat[0]) + box.rotation.z;
@ -380,8 +398,6 @@ function AutoAdjust(boxOp, mouse, header){
// z: -trans_mat[11], // z: -trans_mat[11],
// } // }
// /* // /*
// cos sin x // cos sin x
// -sin cos y // -sin cos y
@ -392,13 +408,10 @@ function AutoAdjust(boxOp, mouse, header){
// z: transform.z, // z: transform.z,
// }; // };
// box.position.x += new_pos.x; // box.position.x += new_pos.x;
// box.position.y += new_pos.y; // box.position.y += new_pos.y;
// box.position.z += new_pos.z; // box.position.z += new_pos.z;
// box.scale.x = marked_object.scale.x; // box.scale.x = marked_object.scale.x;
// box.scale.y = marked_object.scale.y; // box.scale.y = marked_object.scale.y;
// box.scale.z = marked_object.scale.z; // box.scale.z = marked_object.scale.z;
@ -430,15 +443,14 @@ function AutoAdjust(boxOp, mouse, header){
// } // }
// }; // };
this.smart_paste=function(selected_box, add_box, on_box_changed){ this.smart_paste = function (selected_box, add_box, on_box_changed) {
var box = selected_box; var box = selected_box;
if (!box){ if (!box) {
let sceneP = this.mouse.get_mouse_location_in_world() let sceneP = this.mouse.get_mouse_location_in_world();
// trans pos to world local pos // trans pos to world local pos
//let pos = this.data.world.scenePosToLidar(sceneP); //let pos = this.data.world.scenePosToLidar(sceneP);
box = this.paste_bbox(pos, add_box); box = this.paste_bbox(pos, add_box);
} } else if (this.marked_object) {
else if (this.marked_object){
box.scale.x = this.marked_object.ann.psr.scale.x; box.scale.x = this.marked_object.ann.psr.scale.x;
box.scale.y = this.marked_object.ann.psr.scale.y; box.scale.y = this.marked_object.ann.psr.scale.y;
box.scale.z = this.marked_object.ann.psr.scale.z; box.scale.z = this.marked_object.ann.psr.scale.z;
@ -450,14 +462,8 @@ function AutoAdjust(boxOp, mouse, header){
// this.header.mark_changed_flag(); // this.header.mark_changed_flag();
this.boxOp.auto_rotate_xyz(box, null, null, on_box_changed, "noscaling");
this.boxOp.auto_rotate_xyz(box, null, null,
on_box_changed,
"noscaling");
}; };
} }
export { AutoAdjust };
export {AutoAdjust}

@ -1,8 +1,6 @@
import { globalObjectCategory } from "./obj_cfg.js"; import { globalObjectCategory } from "./obj_cfg.js";
function autoAnnotate(world, done, alg) {
function autoAnnotate(world, done, alg){
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
// we defined the xhr // we defined the xhr
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
@ -11,20 +9,31 @@ function autoAnnotate(world, done, alg){
if (this.status == 200) { if (this.status == 200) {
let anns = JSON.parse(this.responseText); let anns = JSON.parse(this.responseText);
anns.map(a=>a.obj_type = globalObjectCategory.guess_obj_type_by_dimension(a.psr.scale)); anns.map(
(a) =>
(a.obj_type = globalObjectCategory.guess_obj_type_by_dimension(
a.psr.scale
))
);
// load annotations // load annotations
world.annotation.reapplyAnnotation(anns); world.annotation.reapplyAnnotation(anns);
if (done) if (done) done();
done();
} }
}; };
xhr.open('GET', "/auto_annotate?"+"scene="+world.frameInfo.scene+"&frame="+world.frameInfo.frame, true); xhr.open(
"GET",
"/auto_annotate?" +
"scene=" +
world.frameInfo.scene +
"&frame=" +
world.frameInfo.frame,
true
);
xhr.send(); xhr.send();
} }
export { autoAnnotate };
export {autoAnnotate}

@ -1,11 +1,10 @@
import * as THREE from './lib/three.module.js'; import * as THREE from "./lib/three.module.js";
import { PCDLoader } from './lib/PCDLoader.js'; import { PCDLoader } from "./lib/PCDLoader.js";
import { matmul, euler_angle_to_rotate_matrix_3by3} from "./util.js" import { matmul, euler_angle_to_rotate_matrix_3by3 } from "./util.js";
//todo: clean arrows //todo: clean arrows
function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName) {
this.world = world; this.world = world;
this.frameInfo = frameInfo; this.frameInfo = frameInfo;
this.name = auxLidarName; this.name = auxLidarName;
@ -17,9 +16,7 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
//this.cssStyleSelector = this.sceneMeta.calib.aux_lidar[this.name].cssstyleselector; //this.cssStyleSelector = this.sceneMeta.calib.aux_lidar[this.name].cssstyleselector;
this.color = this.sceneMeta.calib.aux_lidar[this.name].color; this.color = this.sceneMeta.calib.aux_lidar[this.name].color;
if (!this.color) {
if (!this.color)
{
this.color = [ this.color = [
this.world.data.cfg.point_brightness, this.world.data.cfg.point_brightness,
this.world.data.cfg.point_brightness, this.world.data.cfg.point_brightness,
@ -33,26 +30,21 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
this.preloaded = false; this.preloaded = false;
this.loaded = false; this.loaded = false;
this.go_cmd_received = false; this.go_cmd_received = false;
this.webglScene = null; this.webglScene = null;
this.on_go_finished = null; this.on_go_finished = null;
this.go = function(webglScene, on_go_finished){ this.go = function (webglScene, on_go_finished) {
this.webglScene = webglScene; this.webglScene = webglScene;
if (this.preloaded){ if (this.preloaded) {
if (this.elements){ if (this.elements) {
this.webglScene.add(this.elements.points); this.webglScene.add(this.elements.points);
if (this.showCalibBox) this.webglScene.add(this.calib_box);
if (this.showCalibBox)
this.webglScene.add(this.calib_box);
} }
this.loaded = true; this.loaded = true;
if (on_go_finished) if (on_go_finished) on_go_finished();
on_go_finished();
} }
//anyway we save go cmd //anyway we save go cmd
@ -62,68 +54,64 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
} }
}; };
this.showCalibBox = function(){ this.showCalibBox = function () {
this.showCalibBox = true; this.showCalibBox = true;
this.webglScene.add(this.calib_box); this.webglScene.add(this.calib_box);
}; };
this.hideCalibBox = function(){ this.hideCalibBox = function () {
this.showCalibBox = false; this.showCalibBox = false;
this.webglScene.remove(this.calib_box); this.webglScene.remove(this.calib_box);
}; };
this.get_unoffset_lidar_points = function(){ this.get_unoffset_lidar_points = function () {
if (this.elements){ if (this.elements) {
let pts = this.elements.points.geometry.getAttribute("position").array; let pts = this.elements.points.geometry.getAttribute("position").array;
return pts.map((p,i)=>p-this.world.coordinatesOffset[i %3]); return pts.map((p, i) => p - this.world.coordinatesOffset[i % 3]);
} } else {
else{
return []; return [];
} }
}; };
// todo: what if it's not preloaded yet // todo: what if it's not preloaded yet
this.unload = function(keep_box){ this.unload = function (keep_box) {
if (this.elements){ if (this.elements) {
this.webglScene.remove(this.elements.points); this.webglScene.remove(this.elements.points);
if (!this.showPointsOnly) if (!this.showPointsOnly)
this.elements.arrows.forEach(a=>this.webglScene.remove(a)); this.elements.arrows.forEach((a) => this.webglScene.remove(a));
if (!keep_box) if (!keep_box) this.webglScene.remove(this.calib_box);
this.webglScene.remove(this.calib_box);
} }
this.loaded = false; this.loaded = false;
}; };
// todo: its possible to remove points before preloading, // todo: its possible to remove points before preloading,
this.deleteAll = function(keep_box){ this.deleteAll = function (keep_box) {
if (this.loaded){ if (this.loaded) {
this.unload(); this.unload();
} }
if (this.elements){ if (this.elements) {
//this.scene.remove(this.points); //this.scene.remove(this.points);
this.world.data.dbg.free(); this.world.data.dbg.free();
if (this.elements.points) if (this.elements.points) {
{
this.elements.points.geometry.dispose(); this.elements.points.geometry.dispose();
this.elements.points.material.dispose(); this.elements.points.material.dispose();
} }
if (this.elements.arrows) if (this.elements.arrows) {
{ this.elements.arrows.forEach((a) => {
this.elements.arrows.forEach(a=>{
this.world.data.dbg.free(); this.world.data.dbg.free();
a.geometry.dispose(); a.geometry.dispose();
a.material.dispose(); a.material.dispose();
}) });
} }
this.elements = null; this.elements = null;
} }
if (!keep_box && this.calib_box){ if (!keep_box && this.calib_box) {
this.world.data.dbg.free(); this.world.data.dbg.free();
this.calib_box.geometry.dispose(); this.calib_box.geometry.dispose();
this.calib_box.material.dispose(); this.calib_box.material.dispose();
@ -131,19 +119,15 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
} }
}; };
this.filterPoints = function(position){ this.filterPoints = function (position) {
let filtered_position = []; let filtered_position = [];
if (pointsGlobalConfig.enableFilterPoints) if (pointsGlobalConfig.enableFilterPoints) {
{ for (let i = 0; i <= position.length; i += 3) {
for(let i = 0; i <= position.length; i+=3) if (position[i + 2] <= pointsGlobalConfig.filterPointsZ) {
{
if (position[i+2] <= pointsGlobalConfig.filterPointsZ)
{
filtered_position.push(position[i]); filtered_position.push(position[i]);
filtered_position.push(position[i+1]); filtered_position.push(position[i + 1]);
filtered_position.push(position[i+2]); filtered_position.push(position[i + 2]);
} }
} }
} }
@ -151,19 +135,18 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
return filtered_position; return filtered_position;
}; };
this.preload = function(on_preload_finished){ this.preload = function (on_preload_finished) {
this.on_preload_finished = on_preload_finished; this.on_preload_finished = on_preload_finished;
var loader = new PCDLoader(); var loader = new PCDLoader();
var _self = this; var _self = this;
loader.load( this.frameInfo.get_aux_lidar_path(this.name), loader.load(
this.frameInfo.get_aux_lidar_path(this.name),
//ok //ok
function ( pcd ) { function (pcd) {
var position = pcd.position; var position = pcd.position;
//_self.points_parse_time = new Date().getTime(); //_self.points_parse_time = new Date().getTime();
//console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "parse pionts ", _self.points_parse_time - _self.create_time, "ms"); //console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "parse pionts ", _self.points_parse_time - _self.create_time, "ms");
_self.lidar_points = position; _self.lidar_points = position;
@ -172,36 +155,33 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
_self.calib_box = _self.createCalibBox(); _self.calib_box = _self.createCalibBox();
// install callback for box changing // install callback for box changing
_self.calib_box.on_box_changed = ()=>{ _self.calib_box.on_box_changed = () => {
_self.move_lidar(_self.calib_box); _self.move_lidar(_self.calib_box);
}; };
//position = _self.transformPointsByOffset(position); //position = _self.transformPointsByOffset(position);
position = _self.move_points(_self.calib_box); position = _self.move_points(_self.calib_box);
let elements = _self.buildGeometry(position); let elements = _self.buildGeometry(position);
_self.elements = elements; _self.elements = elements;
//_self.points_backup = mesh; //_self.points_backup = mesh;
_self._afterPreload(); _self._afterPreload();
}, },
// on progress, // on progress,
function(){}, function () {},
// on error // on error
function(){ function () {
//error //error
console.log("load lidar failed."); console.log("load lidar failed.");
_self._afterPreload(); _self._afterPreload();
}, },
// on file loaded // on file loaded
function(){ function () {
//_self.points_readfile_time = new Date().getTime(); //_self.points_readfile_time = new Date().getTime();
//console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "read file ", _self.points_readfile_time - _self.create_time, "ms"); //console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "read file ", _self.points_readfile_time - _self.create_time, "ms");
} }
@ -209,85 +189,99 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
}; };
// internal funcs below // internal funcs below
this._afterPreload = function(){ this._afterPreload = function () {
this.preloaded = true; this.preloaded = true;
console.log(`lidar ${this.auxLidarName} preloaded`); console.log(`lidar ${this.auxLidarName} preloaded`);
if (this.on_preload_finished){ if (this.on_preload_finished) {
this.on_preload_finished(); this.on_preload_finished();
} }
if (this.go_cmd_received){ if (this.go_cmd_received) {
this.go(this.webglScene, this.on_go_finished); this.go(this.webglScene, this.on_go_finished);
} }
}; };
this.createCalibBox = function(){ this.createCalibBox = function () {
if (this.sceneMeta.calib.aux_lidar && this.sceneMeta.calib.aux_lidar[this.name]){ if (
this.sceneMeta.calib.aux_lidar &&
this.sceneMeta.calib.aux_lidar[this.name]
) {
return this.world.annotation.createCuboid( return this.world.annotation.createCuboid(
{ {
x: this.sceneMeta.calib.aux_lidar[this.name].translation[0] + this.coordinatesOffset[0], x:
y: this.sceneMeta.calib.aux_lidar[this.name].translation[1] + this.coordinatesOffset[1], this.sceneMeta.calib.aux_lidar[this.name].translation[0] +
z: this.sceneMeta.calib.aux_lidar[this.name].translation[2] + this.coordinatesOffset[2], this.coordinatesOffset[0],
y:
this.sceneMeta.calib.aux_lidar[this.name].translation[1] +
this.coordinatesOffset[1],
z:
this.sceneMeta.calib.aux_lidar[this.name].translation[2] +
this.coordinatesOffset[2],
}, },
{x:0.5, y:0.5, z:0.5}, { x: 0.5, y: 0.5, z: 0.5 },
{ {
x: this.sceneMeta.calib.aux_lidar[this.name].rotation[0], x: this.sceneMeta.calib.aux_lidar[this.name].rotation[0],
y: this.sceneMeta.calib.aux_lidar[this.name].rotation[1], y: this.sceneMeta.calib.aux_lidar[this.name].rotation[1],
z: this.sceneMeta.calib.aux_lidar[this.name].rotation[2], z: this.sceneMeta.calib.aux_lidar[this.name].rotation[2],
}, },
"lidar", "lidar",
this.name); this.name
);
}else { } else {
return this.world.annotation.createCuboid( return this.world.annotation.createCuboid(
{x: this.coordinatesOffset[0], {
x: this.coordinatesOffset[0],
y: this.coordinatesOffset[1], y: this.coordinatesOffset[1],
z: this.coordinatesOffset[2]}, z: this.coordinatesOffset[2],
{x:0.5, y:0.5, z:0.5}, },
{x:0,y:0,z:0}, { x: 0.5, y: 0.5, z: 0.5 },
{ x: 0, y: 0, z: 0 },
"lidar", "lidar",
this.name); this.name
);
} }
}; };
this.buildPoints = function(position){ this.buildPoints = function (position) {
// build geometry // build geometry
this.world.data.dbg.alloc(); this.world.data.dbg.alloc();
let geometry = new THREE.BufferGeometry(); let geometry = new THREE.BufferGeometry();
if ( position.length > 0 ) if (position.length > 0)
geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); geometry.addAttribute(
"position",
new THREE.Float32BufferAttribute(position, 3)
);
let pointColor = this.color; let pointColor = this.color;
let color=[]; let color = [];
for (var i =0; i< position.length; i+=3){ for (var i = 0; i < position.length; i += 3) {
color.push(pointColor[0]); color.push(pointColor[0]);
color.push(pointColor[1]); color.push(pointColor[1]);
color.push(pointColor[2]); color.push(pointColor[2]);
} }
geometry.addAttribute( 'color', new THREE.Float32BufferAttribute(color, 3 ) ); geometry.addAttribute("color", new THREE.Float32BufferAttribute(color, 3));
geometry.computeBoundingSphere(); geometry.computeBoundingSphere();
// build material // build material
let pointSize = this.sceneMeta.calib.aux_lidar[this.name].point_size; let pointSize = this.sceneMeta.calib.aux_lidar[this.name].point_size;
if (!pointSize) if (!pointSize) pointSize = 1;
pointSize = 1;
let material = new THREE.PointsMaterial( { size: pointSize, vertexColors: THREE.VertexColors } ); let material = new THREE.PointsMaterial({
size: pointSize,
vertexColors: THREE.VertexColors,
});
//material.size = 2; //material.size = 2;
material.sizeAttenuation = false; material.sizeAttenuation = false;
// build mesh // build mesh
let mesh = new THREE.Points( geometry, material ); let mesh = new THREE.Points(geometry, material);
mesh.name = "lidar"; mesh.name = "lidar";
return mesh; return mesh;
}; };
this.buildGeometry = function (position) {
this.buildGeometry = function(position){
let points = this.buildPoints(position); let points = this.buildPoints(position);
return { return {
@ -295,12 +289,12 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
}; };
}; };
this.move_points = function(box){ this.move_points = function (box) {
let points = this.lidar_points; let points = this.lidar_points;
let trans = euler_angle_to_rotate_matrix_3by3(box.rotation); let trans = euler_angle_to_rotate_matrix_3by3(box.rotation);
let rotated_points = matmul(trans, points, 3); let rotated_points = matmul(trans, points, 3);
let translation=[box.position.x, box.position.y, box.position.z]; let translation = [box.position.x, box.position.y, box.position.z];
let translated_points = rotated_points.map((p,i)=>{ let translated_points = rotated_points.map((p, i) => {
return p + translation[i % 3]; return p + translation[i % 3];
}); });
@ -308,10 +302,7 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
return filtered_position; return filtered_position;
}; };
this.move_lidar = function (box) {
this.move_lidar= function(box){
let translated_points = this.move_points(box); let translated_points = this.move_points(box);
let elements = this.buildGeometry(translated_points); let elements = this.buildGeometry(translated_points);
@ -322,82 +313,75 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
this.elements = elements; this.elements = elements;
//_self.points_backup = mesh; //_self.points_backup = mesh;
if (this.go_cmd_received) // this should be always true if (this.go_cmd_received) {
{ // this should be always true
this.webglScene.add(this.elements.points); this.webglScene.add(this.elements.points);
if (!this.showPointsOnly) if (!this.showPointsOnly)
this.elements.arrows.forEach(a=>this.webglScene.add(a)); this.elements.arrows.forEach((a) => this.webglScene.add(a));
} }
}; };
} }
function AuxLidarManager(sceneMeta, world, frameInfo){ function AuxLidarManager(sceneMeta, world, frameInfo) {
this.lidarList = []; this.lidarList = [];
if (world.data.cfg.enableAuxLidar && sceneMeta.aux_lidar){ if (world.data.cfg.enableAuxLidar && sceneMeta.aux_lidar) {
let lidars = []; let lidars = [];
for (let r in sceneMeta.calib.aux_lidar){ for (let r in sceneMeta.calib.aux_lidar) {
if (!sceneMeta.calib.aux_lidar[r].disable) if (!sceneMeta.calib.aux_lidar[r].disable) lidars.push(r);
lidars.push(r);
} }
this.lidarList = lidars.map(name=>{ this.lidarList = lidars.map((name) => {
return new AuxLidar(sceneMeta, world, frameInfo, name); return new AuxLidar(sceneMeta, world, frameInfo, name);
}); });
} }
this.getAllBoxes = function() this.getAllBoxes = function () {
{ if (this.showCalibBox) {
if (this.showCalibBox) return this.lidarList.map((r) => r.calib_box);
{ } else {
return this.lidarList.map(r=>r.calib_box);
}
else
{
return []; return [];
} }
}; };
this.preloaded = function(){ this.preloaded = function () {
for (let r in this.lidarList){ for (let r in this.lidarList) {
if (!this.lidarList[r].preloaded) if (!this.lidarList[r].preloaded) return false;
return false;
} }
return true; return true;
}; };
this.go = function(webglScene, on_go_finished){ this.go = function (webglScene, on_go_finished) {
this.lidarList.forEach(r=>r.go(webglScene, on_go_finished)); this.lidarList.forEach((r) => r.go(webglScene, on_go_finished));
}; };
this.preload = function(on_preload_finished){ this.preload = function (on_preload_finished) {
this.lidarList.forEach(r=>r.preload(on_preload_finished)); this.lidarList.forEach((r) => r.preload(on_preload_finished));
}; };
this.unload = function(){ this.unload = function () {
this.lidarList.forEach(r=>r.unload()); this.lidarList.forEach((r) => r.unload());
}; };
this.deleteAll = function(){ this.deleteAll = function () {
this.lidarList.forEach(r=>r.deleteAll()); this.lidarList.forEach((r) => r.deleteAll());
}; };
this.getOperableObjects = function(){ this.getOperableObjects = function () {
return this.lidarList.flatMap(r=>r.getOperableObjects()); return this.lidarList.flatMap((r) => r.getOperableObjects());
}; };
this.showCalibBox = false; this.showCalibBox = false;
this.showCalibBox = function(){ this.showCalibBox = function () {
this.showCalibBox = true; this.showCalibBox = true;
this.lidarList.forEach(r=>r.showCalibBox()); this.lidarList.forEach((r) => r.showCalibBox());
}; };
this.hideCalibBox = function(){ this.hideCalibBox = function () {
this.showCalibBox = false; this.showCalibBox = false;
this.lidarList.forEach(r=>r.hideCalibBox()); this.lidarList.forEach((r) => r.hideCalibBox());
} };
}; }
export {AuxLidarManager} export { AuxLidarManager };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,116 +1,142 @@
import {
import {rotation_matrix_to_euler_angle,euler_angle_to_rotate_matrix, matmul, transpose} from "./util.js" rotation_matrix_to_euler_angle,
euler_angle_to_rotate_matrix,
matmul,
transpose,
} from "./util.js";
//import {render_2d_image, update_image_box_projection} from "./image.js" //import {render_2d_image, update_image_box_projection} from "./image.js"
function Calib(data, editor){ function Calib(data, editor) {
this.data = data; this.data = data;
this.editor = editor; this.editor = editor;
var euler_angle={x:0, y:0, y:0}; var euler_angle = { x: 0, y: 0, y: 0 };
var translate = {x:0, y:0, z:0}; var translate = { x: 0, y: 0, z: 0 };
this.save_calibration = function(){
this.save_calibration = function () {
var scene_meta = data.meta[data.world.frameInfo.scene]; var scene_meta = data.meta[data.world.frameInfo.scene];
var active_camera_name = data.world.cameras.active_name; var active_camera_name = data.world.cameras.active_name;
var calib = scene_meta.calib.camera[active_camera_name] var calib = scene_meta.calib.camera[active_camera_name];
var extrinsic = calib.extrinsic.map(function(x){return x*1.0;}); var extrinsic = calib.extrinsic.map(function (x) {
return x * 1.0;
});
euler_angle = rotation_matrix_to_euler_angle(extrinsic); euler_angle = rotation_matrix_to_euler_angle(extrinsic);
translate = { translate = {
x: extrinsic[3]*1.0, x: extrinsic[3] * 1.0,
y: extrinsic[7]*1.0, y: extrinsic[7] * 1.0,
z: extrinsic[11]*1.0, z: extrinsic[11] * 1.0,
}; };
console.log(extrinsic, euler_angle, translate); console.log(extrinsic, euler_angle, translate);
let matrix = euler_angle_to_rotate_matrix(euler_angle, translate) let matrix = euler_angle_to_rotate_matrix(euler_angle, translate);
console.log("restoreed matrix",matrix); console.log("restoreed matrix", matrix);
this.editor.infoBox.show("calib", JSON.stringify(matrix)); this.editor.infoBox.show("calib", JSON.stringify(matrix));
} };
this.reset_calibration = function(){ this.reset_calibration = function () {
// to be done // to be done
this.editor.imageContextManager.render_2d_image(); this.editor.imageContextManager.render_2d_image();
} };
this.calib_box = null; this.calib_box = null;
this.show_camera_pos = function(){ this.show_camera_pos = function () {
this.editor.viewManager.mainView.dumpPose(); this.editor.viewManager.mainView.dumpPose();
}; };
// show a manipulating box // show a manipulating box
this.start_calibration = function(){ this.start_calibration = function () {
var scene_meta = this.data.meta[data.world.frameInfo.scene]; var scene_meta = this.data.meta[data.world.frameInfo.scene];
var active_camera_name = this.data.world.cameras.active_name; var active_camera_name = this.data.world.cameras.active_name;
var calib = scene_meta.calib.camera[active_camera_name] var calib = scene_meta.calib.camera[active_camera_name];
var extrinsic = calib.extrinsic.map(function(x){return x*1.0;}); var extrinsic = calib.extrinsic.map(function (x) {
let viewMatrix = [0, -1, 0, 0, //row vector return x * 1.0;
0, 0, -1, 0, });
1, 0, 0, 0, let viewMatrix = [
0, 0, 0, 1]; 0,
function transpose_transmatrix(m){ -1,
0,
0, //row vector
0,
0,
-1,
0,
1,
0,
0,
0,
0,
0,
0,
1,
];
function transpose_transmatrix(m) {
//m=4*4 //m=4*4
return [ return [
m[0],m[4],m[8],m[3], m[0],
m[1],m[5],m[9],m[7], m[4],
m[2],m[6],m[10],m[11], m[8],
m[12],m[13],m[14],m[15], m[3],
m[1],
m[5],
m[9],
m[7],
m[2],
m[6],
m[10],
m[11],
m[12],
m[13],
m[14],
m[15],
]; ];
} }
var op_matrix = matmul (transpose_transmatrix(viewMatrix), var op_matrix = matmul(
transpose_transmatrix(extrinsic), 4); transpose_transmatrix(viewMatrix),
transpose_transmatrix(extrinsic),
4
);
var euler_angle = rotation_matrix_to_euler_angle(op_matrix); var euler_angle = rotation_matrix_to_euler_angle(op_matrix);
var translate = { var translate = {
x: extrinsic[3]*1.0, x: extrinsic[3] * 1.0,
y: extrinsic[7]*1.0, y: extrinsic[7] * 1.0,
z: extrinsic[11]*1.0, z: extrinsic[11] * 1.0,
}; };
console.log(euler_angle, translate); console.log(euler_angle, translate);
this.show_camera_pos(); this.show_camera_pos();
if (!this.calib_box) {
if (!this.calib_box)
{
this.calib_box = this.data.world.annotation.createCuboid( this.calib_box = this.data.world.annotation.createCuboid(
{ {
x: translate.x,// + this.data.world.coordinatesOffset[0], x: translate.x, // + this.data.world.coordinatesOffset[0],
y: translate.y,// + this.data.world.coordinatesOffset[1], y: translate.y, // + this.data.world.coordinatesOffset[1],
z: translate.z, // + this.data.world.coordinatesOffset[2] z: translate.z, // + this.data.world.coordinatesOffset[2]
}, },
{x:1,y:1, z:1}, { x: 1, y: 1, z: 1 },
{ {
x: euler_angle.x, x: euler_angle.x,
y: euler_angle.y, y: euler_angle.y,
z: euler_angle.z z: euler_angle.z,
}, },
"camera", "camera",
"camera" "camera"
); );
this.data.world.scene.add(this.calib_box); this.data.world.scene.add(this.calib_box);
} else {
}
else{
console.log("calib box exists."); console.log("calib box exists.");
this.calib_box.position.x = translate.x;// + this.data.world.coordinatesOffset[0]; this.calib_box.position.x = translate.x; // + this.data.world.coordinatesOffset[0];
this.calib_box.position.y = translate.y;// + this.data.world.coordinatesOffset[1]; this.calib_box.position.y = translate.y; // + this.data.world.coordinatesOffset[1];
this.calib_box.position.z = translate.z;// + this.data.world.coordinatesOffset[2]; this.calib_box.position.z = translate.z; // + this.data.world.coordinatesOffset[2];
this.calib_box.rotation.x = euler_angle.x; this.calib_box.rotation.x = euler_angle.x;
this.calib_box.rotation.y = euler_angle.y; this.calib_box.rotation.y = euler_angle.y;
@ -120,32 +146,30 @@ function Calib(data, editor){
console.log(this.calib_box); console.log(this.calib_box);
this.editor.render(); this.editor.render();
this.calib_box.on_box_changed = () => {
this.calib_box.on_box_changed = ()=>{
console.log("calib box changed."); console.log("calib box changed.");
let real_pos = { let real_pos = {
x: this.calib_box.position.x,// - this.data.world.coordinatesOffset[0], x: this.calib_box.position.x, // - this.data.world.coordinatesOffset[0],
y: this.calib_box.position.y,// - this.data.world.coordinatesOffset[1], y: this.calib_box.position.y, // - this.data.world.coordinatesOffset[1],
z: this.calib_box.position.z,// - this.data.world.coordinatesOffset[2], z: this.calib_box.position.z, // - this.data.world.coordinatesOffset[2],
}; };
let extrinsic = euler_angle_to_rotate_matrix(this.calib_box.rotation, real_pos); let extrinsic = euler_angle_to_rotate_matrix(
calib.extrinsic = transpose_transmatrix(matmul (viewMatrix, extrinsic, 4)); this.calib_box.rotation,
console.log("extrinsic", calib.extrinsic) real_pos
);
calib.extrinsic = transpose_transmatrix(matmul(viewMatrix, extrinsic, 4));
console.log("extrinsic", calib.extrinsic);
console.log("euler", euler_angle, "translate", translate); console.log("euler", euler_angle, "translate", translate);
this.editor.imageContextManager.render_2d_image(); this.editor.imageContextManager.render_2d_image();
} };
}; };
function stop_calibration() function stop_calibration() {
{
//tbd //tbd
}; }
/* /*
function calibrate(ax, value){ function calibrate(ax, value){
@ -189,8 +213,6 @@ function Calib(data, editor){
update_image_box_projection(selected_box); update_image_box_projection(selected_box);
} }
*/ */
}
}; export { Calib };
export {Calib}

@ -1,6 +1,4 @@
class Config {
class Config{
//dataCfg = { //dataCfg = {
//disableLabels: true, //disableLabels: true,
@ -10,7 +8,7 @@ class Config{
enableAuxLidar = false; enableAuxLidar = false;
enableDynamicGroundLevel = true; enableDynamicGroundLevel = true;
coordinateSystem = 'utm'; coordinateSystem = "utm";
point_size = 1; point_size = 1;
point_brightness = 0.6; point_brightness = 0.6;
@ -23,8 +21,7 @@ class Config{
filterPointsZ = 2.0; filterPointsZ = 2.0;
batchModeInstNumber = 20; batchModeInstNumber = 20;
batchModeSubviewSize = {width: 130, height: 450}; batchModeSubviewSize = { width: 130, height: 450 };
// edit on one box, apply to all selected boxes. // edit on one box, apply to all selected boxes.
linkEditorsInBatchMode = false; linkEditorsInBatchMode = false;
@ -39,7 +36,7 @@ class Config{
hideCategory = false; hideCategory = false;
moveStep = 0.01; // ratio, percentage moveStep = 0.01; // ratio, percentage
rotateStep = Math.PI/360; rotateStep = Math.PI / 360;
ignoreDistantObject = true; ignoreDistantObject = true;
@ -58,38 +55,27 @@ class Config{
//projectRadarToImage = true; //projectRadarToImage = true;
//projectLidarToImage = true; //projectLidarToImage = true;
constructor() constructor() {}
{
} readItem(name, defaultValue, castFunc) {
readItem(name, defaultValue, castFunc){
let ret = window.localStorage.getItem(name); let ret = window.localStorage.getItem(name);
if (ret) if (ret) {
{ if (castFunc) return castFunc(ret);
if (castFunc) else return ret;
return castFunc(ret); } else {
else
return ret;
}
else
{
return defaultValue; return defaultValue;
} }
} }
setItem(name, value) setItem(name, value) {
{
this[name] = value; this[name] = value;
if (typeof value == 'object') if (typeof value == "object") value = JSON.stringify(value);
value = JSON.stringify(value);
window.localStorage.setItem(name, value); window.localStorage.setItem(name, value);
} }
toBool(v) toBool(v) {
{ return v === "true";
return v==="true";
} }
saveItems = [ saveItems = [
@ -107,15 +93,14 @@ class Config{
["autoUpdateInterpolatedBoxes", this.toBool], ["autoUpdateInterpolatedBoxes", this.toBool],
]; ];
load() load() {
{ this.saveItems.forEach((item) => {
this.saveItems.forEach(item=>{
let key = item[0]; let key = item[0];
let castFunc = item[1]; let castFunc = item[1];
this[key] = this.readItem(key, this[key], castFunc); this[key] = this.readItem(key, this[key], castFunc);
}) });
} }
}; }
export {Config}; export { Config };

@ -1,53 +1,52 @@
import { globalKeyDownManager } from "./keydown_manager.js"; import { globalKeyDownManager } from "./keydown_manager.js";
import {logger} from "./log.js"; import { logger } from "./log.js";
class ConfigUi{
class ConfigUi {
clickableItems = { clickableItems = {
"#cfg-increase-size": (event)=>{ "#cfg-increase-size": (event) => {
this.editor.data.scale_point_size(1.2); this.editor.data.scale_point_size(1.2);
this.editor.render(); this.editor.render();
this.editor.boxEditorManager.render(); this.editor.boxEditorManager.render();
return false; return false;
}, },
"#cfg-decrease-size": (event)=>{ "#cfg-decrease-size": (event) => {
this.editor.data.scale_point_size(0.8); this.editor.data.scale_point_size(0.8);
this.editor.render(); this.editor.render();
this.editor.boxEditorManager.render(); this.editor.boxEditorManager.render();
return false; return false;
}, },
"#cfg-increase-brightness": (event)=>{ "#cfg-increase-brightness": (event) => {
this.editor.data.scale_point_brightness(1.2); this.editor.data.scale_point_brightness(1.2);
this.editor.render(); this.editor.render();
this.editor.boxEditorManager.render(); this.editor.boxEditorManager.render();
return false; return false;
}, },
"#cfg-decrease-brightness": (event)=>{ "#cfg-decrease-brightness": (event) => {
this.editor.data.scale_point_brightness(0.8); this.editor.data.scale_point_brightness(0.8);
this.editor.render(); this.editor.render();
this.editor.boxEditorManager.render(); this.editor.boxEditorManager.render();
return false; return false;
}, },
"#cfg-take-screenshot": (event)=>{ "#cfg-take-screenshot": (event) => {
this.editor.downloadWebglScreenShot(); this.editor.downloadWebglScreenShot();
return true; return true;
}, },
"#cfg-show-log": (event)=>{ "#cfg-show-log": (event) => {
logger.show(); logger.show();
return true; return true;
}, },
"#cfg-start-calib":(event)=>{ "#cfg-start-calib": (event) => {
this.editor.calib.start_calibration(); this.editor.calib.start_calibration();
return true; return true;
}, },
"#cfg-show-calib":(event)=>{ "#cfg-show-calib": (event) => {
this.editor.calib.save_calibration(); this.editor.calib.save_calibration();
return true; return true;
}, },
@ -57,23 +56,20 @@ class ConfigUi{
// return true; // return true;
// } // }
"#cfg-crop-scene": (event)=>{ "#cfg-crop-scene": (event) => {
this.editor.cropScene.show(); this.editor.cropScene.show();
return true; return true;
}, },
}; };
changeableItems = { changeableItems = {
"#cfg-theme-select": (event) => {
"#cfg-theme-select":(event)=>{
let theme = event.currentTarget.value; let theme = event.currentTarget.value;
//let scheme = document.documentElement.className; //let scheme = document.documentElement.className;
document.documentElement.className = "theme-" + theme;
document.documentElement.className = "theme-"+theme;
pointsGlobalConfig.setItem("theme", theme); pointsGlobalConfig.setItem("theme", theme);
@ -84,61 +80,55 @@ class ConfigUi{
return false; return false;
}, },
"#cfg-hide-box-checkbox":(event)=>{ "#cfg-hide-box-checkbox": (event) => {
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
//let scheme = document.documentElement.className; //let scheme = document.documentElement.className;
if (checked) if (checked) this.editor.data.set_box_opacity(0);
this.editor.data.set_box_opacity(0); else this.editor.data.set_box_opacity(1);
else
this.editor.data.set_box_opacity(1);
this.editor.render(); this.editor.render();
this.editor.boxEditorManager.render(); this.editor.boxEditorManager.render();
return false; return false;
}, },
"#cfg-hide-id-checkbox": (event) => {
"#cfg-hide-id-checkbox":(event)=>{
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
this.editor.floatLabelManager.show_id(!checked); this.editor.floatLabelManager.show_id(!checked);
return false; return false;
}, },
"#cfg-hide-category-checkbox": (event) => {
"#cfg-hide-category-checkbox":(event)=>{
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
this.editor.floatLabelManager.show_category(!checked); this.editor.floatLabelManager.show_category(!checked);
return false; return false;
}, },
"#cfg-hide-circle-ruler-checkbox": (event)=>{ "#cfg-hide-circle-ruler-checkbox": (event) => {
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
this.editor.showRangeCircle(!checked); this.editor.showRangeCircle(!checked);
return false; return false;
}, },
"#cfg-auto-rotate-xy-checkbox": (event)=>{ "#cfg-auto-rotate-xy-checkbox": (event) => {
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableAutoRotateXY", checked); pointsGlobalConfig.setItem("enableAutoRotateXY", checked);
return false; return false;
}, },
'#cfg-auto-update-interpolated-boxes-checkbox': (event)=>{ "#cfg-auto-update-interpolated-boxes-checkbox": (event) => {
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("autoUpdateInterpolatedBoxes", checked); pointsGlobalConfig.setItem("autoUpdateInterpolatedBoxes", checked);
return false; return false;
}, },
"#cfg-color-points-select": (event)=>{ "#cfg-color-points-select": (event) => {
let value = event.currentTarget.value; let value = event.currentTarget.value;
pointsGlobalConfig.setItem("color_points", value); pointsGlobalConfig.setItem("color_points", value);
this.editor.data.worldList.forEach(w=>{ this.editor.data.worldList.forEach((w) => {
w.lidar.color_points(); w.lidar.color_points();
w.lidar.update_points_color(); w.lidar.update_points_color();
}); });
@ -146,7 +136,7 @@ class ConfigUi{
return false; return false;
}, },
"#cfg-color-object-scheme":(event)=>{ "#cfg-color-object-scheme": (event) => {
let value = event.currentTarget.value; let value = event.currentTarget.value;
this.editor.data.set_obj_color_scheme(value); this.editor.data.set_obj_color_scheme(value);
this.editor.render(); this.editor.render();
@ -159,7 +149,7 @@ class ConfigUi{
return false; return false;
}, },
"#cfg-batch-mode-inst-number":(event)=>{ "#cfg-batch-mode-inst-number": (event) => {
let batchSize = parseInt(event.currentTarget.value); let batchSize = parseInt(event.currentTarget.value);
pointsGlobalConfig.setItem("batchModeInstNumber", batchSize); pointsGlobalConfig.setItem("batchModeInstNumber", batchSize);
@ -168,51 +158,49 @@ class ConfigUi{
return false; return false;
}, },
"#cfg-coordinate-system-select": (event)=>{ "#cfg-coordinate-system-select": (event) => {
let coord = event.currentTarget.value; let coord = event.currentTarget.value;
pointsGlobalConfig.setItem("coordinateSystem", coord); pointsGlobalConfig.setItem("coordinateSystem", coord);
this.editor.data.worldList.forEach(w=>{ this.editor.data.worldList.forEach((w) => {
w.calcTransformMatrix(); w.calcTransformMatrix();
}); });
this.editor.render(); this.editor.render();
}, },
"#cfg-data-aux-lidar-checkbox": (event)=>{ "#cfg-data-aux-lidar-checkbox": (event) => {
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableAuxLidar", checked); pointsGlobalConfig.setItem("enableAuxLidar", checked);
return false; return false;
}, },
"#cfg-data-radar-checkbox": (event)=>{ "#cfg-data-radar-checkbox": (event) => {
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableRadar", checked); pointsGlobalConfig.setItem("enableRadar", checked);
return false; return false;
}, },
"#cfg-data-filter-points-checkbox": (event)=>{ "#cfg-data-filter-points-checkbox": (event) => {
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableFilterPoints", checked); pointsGlobalConfig.setItem("enableFilterPoints", checked);
return false; return false;
}, },
"#cfg-data-filter-points-z": (event)=>{ "#cfg-data-filter-points-z": (event) => {
let z = event.currentTarget.value; let z = event.currentTarget.value;
pointsGlobalConfig.setItem("filterPointsZ", z); pointsGlobalConfig.setItem("filterPointsZ", z);
return false; return false;
}, },
"#cfg-data-preload-checkbox": (event) => {
"#cfg-data-preload-checkbox": (event)=>{
let checked = event.currentTarget.checked; let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enablePreload", checked); pointsGlobalConfig.setItem("enablePreload", checked);
return false; return false;
} },
}; };
ignoreItems = [ ignoreItems = [
@ -227,13 +215,9 @@ class ConfigUi{
"#cfg-data", "#cfg-data",
]; ];
subMenus = [ subMenus = ["#cfg-experimental", "#cfg-data"];
"#cfg-experimental",
"#cfg-data",
];
constructor(button, wrapper, editor) constructor(button, wrapper, editor) {
{
this.button = button; this.button = button;
this.wrapper = wrapper; this.wrapper = wrapper;
this.editor = editor; this.editor = editor;
@ -241,107 +225,111 @@ class ConfigUi{
this.dataCfg = editor.data.cfg; this.dataCfg = editor.data.cfg;
this.menu = this.wrapper.querySelector("#config-menu"); this.menu = this.wrapper.querySelector("#config-menu");
this.wrapper.onclick = ()=>{ this.wrapper.onclick = () => {
this.hide(); this.hide();
} };
this.button.onclick = (event)=>{ this.button.onclick = (event) => {
this.show(event.currentTarget); this.show(event.currentTarget);
} };
for (let item in this.clickableItems) for (let item in this.clickableItems) {
{ this.menu.querySelector(item).onclick = (event) => {
this.menu.querySelector(item).onclick = (event)=>{
let ret = this.clickableItems[item](event); let ret = this.clickableItems[item](event);
if (ret) if (ret) {
{
this.hide(); this.hide();
} }
event.stopPropagation(); event.stopPropagation();
} };
} }
for (let item in this.changeableItems) for (let item in this.changeableItems) {
{ this.menu.querySelector(item).onchange = (event) => {
this.menu.querySelector(item).onchange = (event)=>{
let ret = this.changeableItems[item](event); let ret = this.changeableItems[item](event);
if (ret) if (ret) {
{
this.hide(); this.hide();
} }
event.stopPropagation(); event.stopPropagation();
} };
} }
this.ignoreItems.forEach(item=>{ this.ignoreItems.forEach((item) => {
this.menu.querySelector(item).onclick = (event)=>{ this.menu.querySelector(item).onclick = (event) => {
{ {
event.stopPropagation(); event.stopPropagation();
} }
} };
}); });
this.subMenus.forEach(item=>{ this.subMenus.forEach((item) => {
this.menu.querySelector(item).onmouseenter = function(event){ this.menu.querySelector(item).onmouseenter = function (event) {
if (this.timerId) if (this.timerId) {
{
clearTimeout(this.timerId); clearTimeout(this.timerId);
this.timerId = null; this.timerId = null;
} }
event.currentTarget.querySelector(item +"-submenu").style.display="inherit"; event.currentTarget.querySelector(item + "-submenu").style.display =
} "inherit";
};
this.menu.querySelector(item).onmouseleave = function(event){ this.menu.querySelector(item).onmouseleave = function (event) {
let ui = event.currentTarget.querySelector(item +"-submenu"); let ui = event.currentTarget.querySelector(item + "-submenu");
this.timerId = setTimeout(()=>{ this.timerId = setTimeout(() => {
ui.style.display="none"; ui.style.display = "none";
this.timerId = null; this.timerId = null;
}, }, 200);
200); };
}
}); });
this.menu.onclick = (event)=>{ this.menu.onclick = (event) => {
event.stopPropagation(); event.stopPropagation();
}; };
// init ui // init ui
this.menu.querySelector("#cfg-theme-select").value = pointsGlobalConfig.theme; this.menu.querySelector("#cfg-theme-select").value =
this.menu.querySelector("#cfg-data-aux-lidar-checkbox").checked = pointsGlobalConfig.enableAuxLidar; pointsGlobalConfig.theme;
this.menu.querySelector("#cfg-data-radar-checkbox").checked = pointsGlobalConfig.enableRadar; this.menu.querySelector("#cfg-data-aux-lidar-checkbox").checked =
this.menu.querySelector("#cfg-color-points-select").value = pointsGlobalConfig.color_points; pointsGlobalConfig.enableAuxLidar;
this.menu.querySelector("#cfg-coordinate-system-select").value = pointsGlobalConfig.coordinateSystem; this.menu.querySelector("#cfg-data-radar-checkbox").checked =
this.menu.querySelector("#cfg-batch-mode-inst-number").value = pointsGlobalConfig.batchModeInstNumber; pointsGlobalConfig.enableRadar;
this.menu.querySelector("#cfg-data-filter-points-checkbox").checked = pointsGlobalConfig.enableFilterPoints; this.menu.querySelector("#cfg-color-points-select").value =
this.menu.querySelector("#cfg-data-filter-points-z").value = pointsGlobalConfig.filterPointsZ; pointsGlobalConfig.color_points;
this.menu.querySelector("#cfg-hide-id-checkbox").value = pointsGlobalConfig.hideId; this.menu.querySelector("#cfg-coordinate-system-select").value =
this.menu.querySelector("#cfg-hide-category-checkbox").value = pointsGlobalConfig.hideCategory; pointsGlobalConfig.coordinateSystem;
this.menu.querySelector("#cfg-data-preload-checkbox").checked = pointsGlobalConfig.enablePreload; this.menu.querySelector("#cfg-batch-mode-inst-number").value =
this.menu.querySelector("#cfg-auto-rotate-xy-checkbox").checked = pointsGlobalConfig.enableAutoRotateXY; pointsGlobalConfig.batchModeInstNumber;
this.menu.querySelector("#cfg-auto-update-interpolated-boxes-checkbox").checked = pointsGlobalConfig.autoUpdateInterpolatedBoxes; this.menu.querySelector("#cfg-data-filter-points-checkbox").checked =
pointsGlobalConfig.enableFilterPoints;
this.menu.querySelector("#cfg-data-filter-points-z").value =
pointsGlobalConfig.filterPointsZ;
this.menu.querySelector("#cfg-hide-id-checkbox").value =
pointsGlobalConfig.hideId;
this.menu.querySelector("#cfg-hide-category-checkbox").value =
pointsGlobalConfig.hideCategory;
this.menu.querySelector("#cfg-data-preload-checkbox").checked =
pointsGlobalConfig.enablePreload;
this.menu.querySelector("#cfg-auto-rotate-xy-checkbox").checked =
pointsGlobalConfig.enableAutoRotateXY;
this.menu.querySelector(
"#cfg-auto-update-interpolated-boxes-checkbox"
).checked = pointsGlobalConfig.autoUpdateInterpolatedBoxes;
} }
show(target) {
show(target){ this.wrapper.style.display = "inherit";
this.wrapper.style.display="inherit";
this.menu.style.right = "0px"; this.menu.style.right = "0px";
this.menu.style.top = target.offsetHeight + "px"; this.menu.style.top = target.offsetHeight + "px";
globalKeyDownManager.register((event)=>false, 'config'); globalKeyDownManager.register((event) => false, "config");
} }
hide(){ hide() {
globalKeyDownManager.deregister('config'); globalKeyDownManager.deregister("config");
this.wrapper.style.display="none"; this.wrapper.style.display = "none";
} }
} }
export { ConfigUi };
export {ConfigUi}

@ -1,9 +1,7 @@
import { globalKeyDownManager } from "./keydown_manager.js"; import { globalKeyDownManager } from "./keydown_manager.js";
class ContextMenu { class ContextMenu {
constructor(ui) constructor(ui) {
{
this.wrapperUi = ui; this.wrapperUi = ui;
this.menus = { this.menus = {
@ -17,20 +15,17 @@ class ContextMenu {
//thisSubMenu: ui.querySelector("#cm-this-submenu"), //thisSubMenu: ui.querySelector("#cm-this-submenu"),
}; };
for (let m in this.menus){ for (let m in this.menus) {
for (let i = 0; i < this.menus[m].children.length; i++) for (let i = 0; i < this.menus[m].children.length; i++) {
{ this.menus[m].children[i].onclick = (event) => {
this.menus[m].children[i].onclick = (event) =>
{
//event.preventDefault(); //event.preventDefault();
event.stopPropagation(); event.stopPropagation();
let ret = this.handler.handleContextMenuEvent(event); let ret = this.handler.handleContextMenuEvent(event);
if (ret) if (ret) {
{
this.hide(); this.hide();
} }
} };
} }
} }
@ -42,67 +37,59 @@ class ContextMenu {
//"#cm-this": "#cm-this-submenu", //"#cm-this": "#cm-this-submenu",
}; };
for (let item in motherMenu) {
for (let item in motherMenu)
{
let menu = ui.querySelector(item); let menu = ui.querySelector(item);
menu.onclick = (event)=>{ menu.onclick = (event) => {
return false; return false;
} };
let self = this; let self = this;
menu.onmouseenter = function(event){ menu.onmouseenter = function (event) {
if (this.timerId) if (this.timerId) {
{
clearTimeout(this.timerId); clearTimeout(this.timerId);
this.timerId = null; this.timerId = null;
} }
let menu = event.currentTarget.querySelector(motherMenu[item]); let menu = event.currentTarget.querySelector(motherMenu[item]);
menu.style.display="inherit"; menu.style.display = "inherit";
let motherMenuRect = event.currentTarget.getBoundingClientRect(); let motherMenuRect = event.currentTarget.getBoundingClientRect();
let posX = motherMenuRect.right; let posX = motherMenuRect.right;
let posY = motherMenuRect.bottom; let posY = motherMenuRect.bottom;
if (self.wrapperUi.clientHeight < posY + menu.clientHeight){ if (self.wrapperUi.clientHeight < posY + menu.clientHeight) {
menu.style.bottom = "0%"; menu.style.bottom = "0%";
menu.style.top = ""; menu.style.top = "";
} } else {
else{
menu.style.top = "0%"; menu.style.top = "0%";
menu.style.bottom = ""; menu.style.bottom = "";
} }
if (self.wrapperUi.clientWidth < posX + menu.clientWidth) {
if (self.wrapperUi.clientWidth < posX + menu.clientWidth){
menu.style.right = "100%"; menu.style.right = "100%";
menu.style.left = ""; menu.style.left = "";
} } else {
else{
menu.style.left = "100%"; menu.style.left = "100%";
menu.style.right = ""; menu.style.right = "";
} }
} };
menu.onmouseleave = function(event){ menu.onmouseleave = function (event) {
let ui = event.currentTarget.querySelector(motherMenu[item]); let ui = event.currentTarget.querySelector(motherMenu[item]);
this.timerId = setTimeout(()=>{ this.timerId = setTimeout(() => {
ui.style.display="none"; ui.style.display = "none";
this.timerId = null; this.timerId = null;
}, }, 200);
200); };
}
} }
this.wrapperUi.onclick = (event) => {
this.wrapperUi.onclick = (event)=>{
this.hide(); this.hide();
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
}; };
this.wrapperUi.oncontextmenu = (event)=>{ this.wrapperUi.oncontextmenu = (event) => {
//event.currentTarget.style.display="none"; //event.currentTarget.style.display="none";
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -110,90 +97,72 @@ class ContextMenu {
} }
// install dynamic menu, like object new // install dynamic menu, like object new
installMenu(name, ui, funcHandler) installMenu(name, ui, funcHandler) {
{
this.menus[name] = ui; this.menus[name] = ui;
for (let i = 0; i < ui.children.length; i++){ for (let i = 0; i < ui.children.length; i++) {
ui.children[i].onclick = (event) => ui.children[i].onclick = (event) => {
{
//event.preventDefault(); //event.preventDefault();
event.stopPropagation(); event.stopPropagation();
let ret = funcHandler(event); let ret = funcHandler(event);
if (ret) if (ret) {
{
this.hide(); this.hide();
} }
} };
} }
} }
hide() hide() {
{
this.wrapperUi.style.display = "none"; this.wrapperUi.style.display = "none";
globalKeyDownManager.deregister('context menu'); globalKeyDownManager.deregister("context menu");
} }
show(name, posX, posY, handler, funcSetPos) show(name, posX, posY, handler, funcSetPos) {
{
this.handler = handler; this.handler = handler;
//hide all others //hide all others
for (let m in this.menus) { for (let m in this.menus) {
if (m !== name) if (m !== name) this.menus[m].style.display = "none";
this.menus[m].style.display = 'none';
} }
// show // show
this.wrapperUi.style.display = "block"; this.wrapperUi.style.display = "block";
let menu = this.menus[name] let menu = this.menus[name];
menu.style.display = "inherit"; menu.style.display = "inherit";
this.currentMenu = menu; this.currentMenu = menu;
if (funcSetPos) if (funcSetPos) {
{
funcSetPos(menu); funcSetPos(menu);
} else {
if (this.wrapperUi.clientHeight < posY + menu.clientHeight) {
menu.style.top = this.wrapperUi.clientHeight - menu.clientHeight + "px";
} else {
menu.style.top = posY + "px";
} }
else{
if (this.wrapperUi.clientHeight < posY + menu.clientHeight){
menu.style.top = (this.wrapperUi.clientHeight - menu.clientHeight) + "px";
}
else{
menu.style.top = posY+"px";
}
if (this.wrapperUi.clientWidth < posX + menu.clientWidth){ if (this.wrapperUi.clientWidth < posX + menu.clientWidth) {
menu.style.left = (this.wrapperUi.clientWidth - menu.clientWidth) + "px"; menu.style.left = this.wrapperUi.clientWidth - menu.clientWidth + "px";
} else {
menu.style.left = posX + "px";
} }
else{
menu.style.left = posX+"px";
} }
} globalKeyDownManager.register((event) => {
globalKeyDownManager.register((event)=>{
let menuRect = this.currentMenu.getBoundingClientRect(); let menuRect = this.currentMenu.getBoundingClientRect();
let ret = this.handler.handleContextMenuKeydownEvent(event, let ret = this.handler.handleContextMenuKeydownEvent(event, {
{x: menuRect.left, y: menuRect.top}); x: menuRect.left,
if (!ret) y: menuRect.top,
{ });
if (!ret) {
this.hide(); this.hide();
} }
return false; // false means don't propogate return false; // false means don't propogate
}, 'context menu'); }, "context menu");
} }
}
export { ContextMenu };
};
export {ContextMenu};

@ -1,13 +1,7 @@
import { PopupDialog } from "./popup_dialog.js"; import { PopupDialog } from "./popup_dialog.js";
class CropScene extends PopupDialog {
class CropScene extends PopupDialog{ constructor(ui, editor) {
constructor(ui, editor)
{
super(ui); super(ui);
this.ui = ui; //wrapper this.ui = ui; //wrapper
@ -15,10 +9,9 @@ class CropScene extends PopupDialog{
this.contentUi = this.ui.querySelector("#content"); this.contentUi = this.ui.querySelector("#content");
let self = this; let self = this;
this.ui.querySelector("#btn-generate").onclick = (event)=>{ this.ui.querySelector("#btn-generate").onclick = (event) => {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
// we defined the xhr // we defined the xhr
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
@ -26,39 +19,36 @@ class CropScene extends PopupDialog{
if (this.status == 200) { if (this.status == 200) {
let ret = JSON.parse(this.responseText); let ret = JSON.parse(this.responseText);
self.contentUi.querySelector("#log").innerText = JSON.stringify(ret, null,"\t"); self.contentUi.querySelector("#log").innerText = JSON.stringify(
ret,
null,
"\t"
);
} }
}; };
xhr.open('POST', "/cropscene", true); xhr.open("POST", "/cropscene", true);
let para={ let para = {
rawSceneId: this.editor.data.world.frameInfo.scene, rawSceneId: this.editor.data.world.frameInfo.scene,
//id: this.ui.querySelector("#scene-id").value, //id: this.ui.querySelector("#scene-id").value,
desc: this.ui.querySelector("#scene-desc").value, desc: this.ui.querySelector("#scene-desc").value,
startTime: this.ui.querySelector("#scene-start-time").value, startTime: this.ui.querySelector("#scene-start-time").value,
seconds: this.ui.querySelector("#scene-seconds").value seconds: this.ui.querySelector("#scene-seconds").value,
}; };
xhr.send(JSON.stringify(para)); xhr.send(JSON.stringify(para));
} };
} }
show() {
show()
{
let frameInfo = this.editor.data.world.frameInfo; let frameInfo = this.editor.data.world.frameInfo;
this.ui.querySelector("#scene-start-time").value=parseInt(frameInfo.frame)-10; this.ui.querySelector("#scene-start-time").value =
this.ui.querySelector("#scene-seconds").value=20; parseInt(frameInfo.frame) - 10;
this.ui.querySelector("#scene-seconds").value = 20;
this.contentUi.querySelector("#log").innerText = ""; this.contentUi.querySelector("#log").innerText = "";
super.show(); super.show();
} }
} }
export { CropScene };
export {CropScene};

@ -1,47 +1,39 @@
import { World } from "./world.js";
import { Debug } from "./debug.js";
import { logger } from "./log.js";
class Data {
import {World} from "./world.js"; constructor(cfg) {
import {Debug} from "./debug.js";
import {logger} from "./log.js"
class Data
{
constructor(cfg)
{
this.cfg = cfg; this.cfg = cfg;
} }
async readSceneList() async readSceneList() {
{
const req = new Request("/get_all_scene_desc"); const req = new Request("/get_all_scene_desc");
let init = { let init = {
method: 'GET', method: "GET",
//body: JSON.stringify({"points": data}) //body: JSON.stringify({"points": data})
}; };
// we defined the xhr // we defined the xhr
return fetch(req, init) return fetch(req, init)
.then(response=>{ .then((response) => {
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
}else{ } else {
return response.json(); return response.json();
} }
}) })
.then(ret=> .then((ret) => {
{
console.log(ret); console.log(ret);
this.sceneDescList = ret; this.sceneDescList = ret;
return ret; return ret;
}) })
.catch(reject=>{ .catch((reject) => {
console.log("error read scene list!"); console.log("error read scene list!");
}); });
} }
async init(){ async init() {
await this.readSceneList(); await this.readSceneList();
} }
@ -49,105 +41,101 @@ class Data
// place world by a offset so they don't overlap // place world by a offset so they don't overlap
dbg = new Debug(); dbg = new Debug();
worldGap=1000.0; worldGap = 1000.0;
worldList=[]; worldList = [];
MaxWorldNumber=80; MaxWorldNumber = 80;
createWorldIndex = 0; // this index shall not repeat, so it increases permanently createWorldIndex = 0; // this index shall not repeat, so it increases permanently
async getWorld(sceneName, frame, on_preload_finished){ async getWorld(sceneName, frame, on_preload_finished) {
// find in list // find in list
if (!this.meta[sceneName]){ if (!this.meta[sceneName]) {
await this.readSceneMetaData(sceneName) await this.readSceneMetaData(sceneName);
} }
if (!this.meta[sceneName]) if (!this.meta[sceneName]) {
{
logger.log("load scene failed", sceneName); logger.log("load scene failed", sceneName);
return null; return null;
} }
let world = this.worldList.find((w)=>{ let world = this.worldList.find((w) => {
return w.frameInfo.scene == sceneName && w.frameInfo.frame == frame; return w.frameInfo.scene == sceneName && w.frameInfo.frame == frame;
}) });
if (world) // found! if (world)
// found!
return world; return world;
world = this._createWorld(sceneName, frame, on_preload_finished); world = this._createWorld(sceneName, frame, on_preload_finished);
return world; return world;
}; }
_createWorld(sceneName, frame, on_preload_finished){
let [x,y,z] = this.allocateOffset(); _createWorld(sceneName, frame, on_preload_finished) {
console.log("create world",x,y,z); let [x, y, z] = this.allocateOffset();
let world = new World(this, sceneName, frame, [this.worldGap*x, this.worldGap*y, this.worldGap*z], on_preload_finished); console.log("create world", x, y, z);
world.offsetIndex = [x,y,z]; let world = new World(
this,
sceneName,
frame,
[this.worldGap * x, this.worldGap * y, this.worldGap * z],
on_preload_finished
);
world.offsetIndex = [x, y, z];
this.createWorldIndex++; this.createWorldIndex++;
this.worldList.push(world); this.worldList.push(world);
return world; return world;
}
}; findWorld(sceneName, frameIndex) {
let world = this.worldList.find((w) => {
findWorld(sceneName, frameIndex){ return (
let world = this.worldList.find((w)=>{ w.frameInfo.scene == sceneName && w.frameInfo.frame_index == frameIndex
return w.frameInfo.scene == sceneName && w.frameInfo.frame_index == frameIndex; );
}) });
if (world) // found! if (world)
// found!
return world; return world;
else else return null;
return null; }
};
offsetList = [[0,0,0]]; offsetList = [[0, 0, 0]];
lastSeedOffset = [0,0,0]; lastSeedOffset = [0, 0, 0];
offsetsAliveCount = 0; offsetsAliveCount = 0;
allocateOffset() allocateOffset() {
{
// we need to make sure the first frame loaded in a scene // we need to make sure the first frame loaded in a scene
// got to locate in [0,0,0] // got to locate in [0,0,0]
if (this.offsetsAliveCount == 0) if (this.offsetsAliveCount == 0) {
{
//reset offsets. //reset offsets.
this.offsetList = [[0,0,0]]; this.offsetList = [[0, 0, 0]];
this.lastSeedOffset = [0,0,0]; this.lastSeedOffset = [0, 0, 0];
} }
if (this.offsetList.length == 0) {
let [x, y, z] = this.lastSeedOffset;
if (x == y) {
if (this.offsetList.length == 0) x = x + 1;
{
let [x,y,z] = this.lastSeedOffset;
if (x == y)
{
x = x+1;
y = 0; y = 0;
} } else {
else y = y + 1;
{
y = y+1;
} }
this.lastSeedOffset = [x, y, 0]; this.lastSeedOffset = [x, y, 0];
this.offsetList.push([x,y,0]); this.offsetList.push([x, y, 0]);
if (x != 0) this.offsetList.push([-x,y,0]); if (x != 0) this.offsetList.push([-x, y, 0]);
if (y != 0) this.offsetList.push([x,-y,0]); if (y != 0) this.offsetList.push([x, -y, 0]);
if (x * y != 0) this.offsetList.push([-x,-y,0]); if (x * y != 0) this.offsetList.push([-x, -y, 0]);
if (x != y) { if (x != y) {
this.offsetList.push([y,x,0]); this.offsetList.push([y, x, 0]);
if (y != 0) this.offsetList.push([-y,x,0]); if (y != 0) this.offsetList.push([-y, x, 0]);
if (x != 0) this.offsetList.push([y,-x,0]); if (x != 0) this.offsetList.push([y, -x, 0]);
if (x * y != 0) this.offsetList.push([-y,-x,0]); if (x * y != 0) this.offsetList.push([-y, -x, 0]);
} }
} }
@ -155,117 +143,113 @@ class Data
this.offsetsAliveCount++; this.offsetsAliveCount++;
return ret; return ret;
}; }
returnOffset(offset) returnOffset(offset) {
{
this.offsetList.push(offset); this.offsetList.push(offset);
this.offsetsAliveCount--; this.offsetsAliveCount--;
}; }
deleteDistantWorlds(world){ deleteDistantWorlds(world) {
let currentWorldIndex = world.frameInfo.frame_index; let currentWorldIndex = world.frameInfo.frame_index;
let disposable = (w)=>{ let disposable = (w) => {
let distant = Math.abs(w.frameInfo.frame_index - currentWorldIndex)>this.MaxWorldNumber; let distant =
Math.abs(w.frameInfo.frame_index - currentWorldIndex) >
this.MaxWorldNumber;
let active = w.everythingDone; let active = w.everythingDone;
if (w.annotation.modified) if (w.annotation.modified) {
{
console.log("deleting world not saved. stop."); console.log("deleting world not saved. stop.");
} }
return distant && !active && !w.annotation.modified; return distant && !active && !w.annotation.modified;
} };
let distantWorldList = this.worldList.filter(w=>disposable(w)); let distantWorldList = this.worldList.filter((w) => disposable(w));
distantWorldList.forEach(w=>{ distantWorldList.forEach((w) => {
this.returnOffset(w.offsetIndex); this.returnOffset(w.offsetIndex);
w.deleteAll(); w.deleteAll();
}); });
this.worldList = this.worldList.filter((w) => !disposable(w));
}
this.worldList = this.worldList.filter(w=>!disposable(w)); deleteOtherWorldsExcept = function (keepScene) {
};
deleteOtherWorldsExcept=function(keepScene){
// release resources if scene changed // release resources if scene changed
this.worldList.forEach(w=>{ this.worldList.forEach((w) => {
if (w.frameInfo.scene != keepScene){ if (w.frameInfo.scene != keepScene) {
this.returnOffset(w.offsetIndex); this.returnOffset(w.offsetIndex);
w.deleteAll(); w.deleteAll();
this.removeRefEgoPoseOfScene(w.frameInfo.scene); this.removeRefEgoPoseOfScene(w.frameInfo.scene);
} }
}) });
this.worldList = this.worldList.filter(w=>w.frameInfo.scene==keepScene); this.worldList = this.worldList.filter(
(w) => w.frameInfo.scene == keepScene
);
}; };
refEgoPose = {};
refEgoPose={}; getRefEgoPose(sceneName, currentPose) {
getRefEgoPose(sceneName, currentPose) if (this.refEgoPose[sceneName]) {
{
if (this.refEgoPose[sceneName]){
return this.refEgoPose[sceneName]; return this.refEgoPose[sceneName];
} } else {
else{
this.refEgoPose[sceneName] = currentPose; this.refEgoPose[sceneName] = currentPose;
return currentPose; return currentPose;
} }
} }
removeRefEgoPoseOfScene(sceneName) removeRefEgoPoseOfScene(sceneName) {
{ if (this.refEgoPose[sceneName]) delete this.refEgoPose[sceneName];
if (this.refEgoPose[sceneName])
delete this.refEgoPose[sceneName];
} }
forcePreloadScene(sceneName, currentWorld){ forcePreloadScene(sceneName, currentWorld) {
//this.deleteOtherWorldsExcept(sceneName); //this.deleteOtherWorldsExcept(sceneName);
let meta = currentWorld.sceneMeta; let meta = currentWorld.sceneMeta;
let currentWorldIndex = currentWorld.frameInfo.frame_index; let currentWorldIndex = currentWorld.frameInfo.frame_index;
let startIndex = Math.max(0, currentWorldIndex - this.MaxWorldNumber/2); let startIndex = Math.max(0, currentWorldIndex - this.MaxWorldNumber / 2);
let endIndex = Math.min(meta.frames.length, startIndex + this.MaxWorldNumber); let endIndex = Math.min(
meta.frames.length,
startIndex + this.MaxWorldNumber
);
this._doPreload(sceneName, startIndex, endIndex); this._doPreload(sceneName, startIndex, endIndex);
logger.log(`${endIndex - startIndex} frames created`); logger.log(`${endIndex - startIndex} frames created`);
} }
preloadScene(sceneName, currentWorld){ preloadScene(sceneName, currentWorld) {
// clean other scenes. // clean other scenes.
this.deleteOtherWorldsExcept(sceneName); this.deleteOtherWorldsExcept(sceneName);
this.deleteDistantWorlds(currentWorld); this.deleteDistantWorlds(currentWorld);
if (!this.cfg.enablePreload) if (!this.cfg.enablePreload) return;
return;
this.forcePreloadScene(sceneName, currentWorld); this.forcePreloadScene(sceneName, currentWorld);
}
}; _doPreload(sceneName, startIndex, endIndex) {
_doPreload(sceneName, startIndex, endIndex)
{
let meta = this.getMetaBySceneName(sceneName); let meta = this.getMetaBySceneName(sceneName);
let numLoaded = 0; let numLoaded = 0;
let _need_create = (frame)=>{ let _need_create = (frame) => {
let world = this.worldList.find((w)=>{ let world = this.worldList.find((w) => {
return w.frameInfo.scene == sceneName && w.frameInfo.frame == frame; return w.frameInfo.scene == sceneName && w.frameInfo.frame == frame;
}) });
return !world; return !world;
} };
let _do_create = (frame)=>{ let _do_create = (frame) => {
this._createWorld(sceneName, frame); this._createWorld(sceneName, frame);
numLoaded++; numLoaded++;
}; };
let pendingFrames = meta.frames.slice(startIndex, endIndex).filter(_need_create); let pendingFrames = meta.frames
.slice(startIndex, endIndex)
.filter(_need_create);
logger.log(`preload ${meta.scene} ${pendingFrames}`); logger.log(`preload ${meta.scene} ${pendingFrames}`);
// if (numLoaded > 0){ // if (numLoaded > 0){
@ -276,70 +260,67 @@ class Data
pendingFrames.forEach(_do_create); pendingFrames.forEach(_do_create);
} }
reloadAllAnnotation = function (done) {
reloadAllAnnotation=function(done){ this.worldList.forEach((w) => w.reloadAnnotation(done));
this.worldList.forEach(w=>w.reloadAnnotation(done));
}; };
onAnnotationUpdatedByOthers(scene, frames){ onAnnotationUpdatedByOthers(scene, frames) {
frames.forEach(f=>{ frames.forEach((f) => {
let world = this.worldList.find(w=>(w.frameInfo.scene==scene && w.frameInfo.frame==f)); let world = this.worldList.find(
if (world) (w) => w.frameInfo.scene == scene && w.frameInfo.frame == f
world.annotation.reloadAnnotation(); );
}) if (world) world.annotation.reloadAnnotation();
}; });
}
webglScene = null; webglScene = null;
set_webglScene=function(scene, mainScene){ set_webglScene = function (scene, mainScene) {
this.webglScene = scene; this.webglScene = scene;
this.webglMainScene = mainScene; this.webglMainScene = mainScene;
}; };
scale_point_size(v){ scale_point_size(v) {
this.cfg.point_size *= v; this.cfg.point_size *= v;
// if (this.world){ // if (this.world){
// this.world.lidar.set_point_size(this.cfg.point_size); // this.world.lidar.set_point_size(this.cfg.point_size);
// } // }
this.worldList.forEach(w=>{ this.worldList.forEach((w) => {
w.lidar.set_point_size(this.cfg.point_size); w.lidar.set_point_size(this.cfg.point_size);
}); });
}; }
scale_point_brightness(v){ scale_point_brightness(v) {
this.cfg.point_brightness *= v; this.cfg.point_brightness *= v;
// if (this.world){ // if (this.world){
// this.world.lidar.recolor_all_points(); // this.world.lidar.recolor_all_points();
// } // }
this.worldList.forEach(w=>{ this.worldList.forEach((w) => {
w.lidar.recolor_all_points(); w.lidar.recolor_all_points();
}) });
}; }
set_box_opacity(opacity){ set_box_opacity(opacity) {
this.cfg.box_opacity = opacity; this.cfg.box_opacity = opacity;
this.worldList.forEach(w=>{ this.worldList.forEach((w) => {
w.annotation.set_box_opacity(this.cfg.box_opacity); w.annotation.set_box_opacity(this.cfg.box_opacity);
}); });
}; }
toggle_background(){ toggle_background() {
this.cfg.show_background = !this.cfg.show_background; this.cfg.show_background = !this.cfg.show_background;
if (this.cfg.show_background){ if (this.cfg.show_background) {
this.world.lidar.cancel_highlight(); this.world.lidar.cancel_highlight();
} } else {
else{
this.world.lidar.hide_background(); this.world.lidar.hide_background();
} }
}; }
set_obj_color_scheme(scheme){
set_obj_color_scheme(scheme) {
pointsGlobalConfig.color_obj = scheme; pointsGlobalConfig.color_obj = scheme;
// if (pointsGlobalConfig.color_obj != "no"){ // if (pointsGlobalConfig.color_obj != "no"){
@ -355,23 +336,19 @@ class Data
// this.world.lidar.update_points_color(); // this.world.lidar.update_points_color();
// this.world.annotation.color_boxes(); // this.world.annotation.color_boxes();
// toto: move to world // toto: move to world
this.worldList.forEach(w=>{ this.worldList.forEach((w) => {
if (pointsGlobalConfig.color_obj == "no") if (pointsGlobalConfig.color_obj == "no") {
{
w.lidar.color_points(); w.lidar.color_points();
} } else {
else
{
w.lidar.color_objects(); w.lidar.color_objects();
} }
w.lidar.update_points_color(); w.lidar.update_points_color();
w.annotation.color_boxes(); w.annotation.color_boxes();
}) });
}; }
// active_camera_name = ""; // active_camera_name = "";
@ -390,7 +367,7 @@ class Data
// return name; // return name;
// }; // };
world=null; world = null;
// this.future_world_buffer = []; // this.future_world_buffer = [];
// this.put_world_into_buffer= function(world){ // this.put_world_into_buffer= function(world){
@ -408,61 +385,52 @@ class Data
// this.worldList.push(world); // this.worldList.push(world);
// }; // };
activate_world= function(world, on_finished, dontDestroyOldWorld){ activate_world = function (world, on_finished, dontDestroyOldWorld) {
if (dontDestroyOldWorld) {
if (dontDestroyOldWorld){
world.activate(this.webglScene, null, on_finished); world.activate(this.webglScene, null, on_finished);
} } else {
else{
var old_world = this.world; // current world, should we get current world later? var old_world = this.world; // current world, should we get current world later?
this.world = world; // swich when everything is ready. otherwise data.world is half-baked, causing mysterious problems. this.world = world; // swich when everything is ready. otherwise data.world is half-baked, causing mysterious problems.
world.activate(this.webglMainScene, world.activate(
function(){ this.webglMainScene,
if (old_world) function () {
old_world.unload(); if (old_world) old_world.unload();
}, },
on_finished); on_finished
);
} }
}; };
meta = {}; //meta data meta = {}; //meta data
getMetaBySceneName = (sceneName)=>{ getMetaBySceneName = (sceneName) => {
return this.meta[sceneName]; return this.meta[sceneName];
}; };
get_current_world_scene_meta() {
get_current_world_scene_meta(){
return this.getMetaBySceneName(this.world.frameInfo.scene); return this.getMetaBySceneName(this.world.frameInfo.scene);
}; }
readSceneMetaData(sceneName) readSceneMetaData(sceneName) {
{ let self = this;
let self =this; return new Promise(function (resolve, reject) {
return new Promise(function(resolve, reject){
let xhr = new XMLHttpRequest(); let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
if (this.readyState != 4) if (this.readyState != 4) return;
return;
if (this.status == 200) { if (this.status == 200) {
let sceneMeta = JSON.parse(this.responseText); let sceneMeta = JSON.parse(this.responseText);
self.meta[sceneName] = sceneMeta; self.meta[sceneName] = sceneMeta;
resolve(sceneMeta); resolve(sceneMeta);
} }
}; };
xhr.open('GET', `/scenemeta?scene=${sceneName}`, true); xhr.open("GET", `/scenemeta?scene=${sceneName}`, true);
xhr.send(); xhr.send();
}); });
} }
}; }
export {Data};
export { Data };

@ -1,18 +1,17 @@
function Debug(){ function Debug() {
this.res_count = 0; this.res_count = 0;
this.alloc = function(){ this.alloc = function () {
this.res_count++; this.res_count++;
}; };
this.free = function(){ this.free = function () {
this.res_count--; this.res_count--;
}; };
this.dump = function(){ this.dump = function () {
console.log(`number of resources: ${this.res_count}`); console.log(`number of resources: ${this.res_count}`);
} };
}; }
export {Debug};
export { Debug };

File diff suppressed because it is too large Load Diff

@ -1,26 +1,16 @@
class EgoPose {
constructor(sceneMeta, world, frameInfo) {
class EgoPose
{
constructor(sceneMeta, world, frameInfo)
{
this.world = world; this.world = world;
this.data = this.world.data; this.data = this.world.data;
this.sceneMeta = sceneMeta; this.sceneMeta = sceneMeta;
} }
preload(on_preload_finished) {
preload(on_preload_finished)
{
this.on_preload_finished = on_preload_finished; this.on_preload_finished = on_preload_finished;
this.load_ego_pose(); this.load_ego_pose();
}; }
load_ego_pose(){
load_ego_pose() {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
// we defined the xhr // we defined the xhr
var _self = this; var _self = this;
@ -35,44 +25,41 @@ class EgoPose
console.log(_self.world.frameInfo.frame, "egopose", "loaded"); console.log(_self.world.frameInfo.frame, "egopose", "loaded");
_self.preloaded = true; _self.preloaded = true;
if (_self.on_preload_finished){ if (_self.on_preload_finished) {
_self.on_preload_finished(); _self.on_preload_finished();
} }
if (_self.go_cmd_received){ if (_self.go_cmd_received) {
_self.go(this.webglScene, this.on_go_finished); _self.go(this.webglScene, this.on_go_finished);
} }
// end of state change: it can be after some time (async) // end of state change: it can be after some time (async)
}; };
xhr.open('GET', "/load_ego_pose"+"?scene="+this.world.frameInfo.scene+"&frame="+this.world.frameInfo.frame, true); xhr.open(
"GET",
"/load_ego_pose" +
"?scene=" +
this.world.frameInfo.scene +
"&frame=" +
this.world.frameInfo.frame,
true
);
xhr.send(); xhr.send();
}; }
go_cmd_received = false; go_cmd_received = false;
on_go_finished = null; on_go_finished = null;
go(webglScene, on_go_finished) go(webglScene, on_go_finished) {
{ if (this.preloaded) {
if (this.preloaded){ if (on_go_finished) on_go_finished();
if (on_go_finished)
on_go_finished();
} else { } else {
this.go_cmd_received = true; this.go_cmd_received = true;
this.on_go_finished = on_go_finished; this.on_go_finished = on_go_finished;
} }
}; }
unload()
{
};
unload() {}
} }
export { EgoPose };
export{EgoPose}

@ -1,30 +1,27 @@
import { logger } from "./log.js"; import { logger } from "./log.js";
function checkScene(scene) {
function checkScene(scene)
{
const req = new Request(`/checkscene?scene=${scene}`); const req = new Request(`/checkscene?scene=${scene}`);
let init = { let init = {
method: 'GET', method: "GET",
//body: JSON.stringify({"points": data}) //body: JSON.stringify({"points": data})
}; };
// we defined the xhr // we defined the xhr
return fetch(req, init) return fetch(req, init)
.then(response=>{ .then((response) => {
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
}else{ } else {
return response.json(); return response.json();
} }
}) })
.then(ret=> .then((ret) => {
{
logger.setErrorsContent(ret); logger.setErrorsContent(ret);
}) })
.catch(reject=>{ .catch((reject) => {
console.log("error check scene!"); console.log("error check scene!");
}); });
} }
export {checkScene} export { checkScene };

@ -1,209 +1,170 @@
import { psr_to_xyz } from "./util.js";
import * as THREE from "./lib/three.module.js";
import {psr_to_xyz} from "./util.js"
import * as THREE from './lib/three.module.js';
import { globalObjectCategory } from "./obj_cfg.js"; import { globalObjectCategory } from "./obj_cfg.js";
class FastToolBox{ class FastToolBox {
constructor(ui, eventHandler) constructor(ui, eventHandler) {
{
let self = this; let self = this;
this.ui = ui; this.ui = ui;
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.installEventHandler(); this.installEventHandler();
this.ui.querySelector("#attr-editor").onmouseenter=function(event){ this.ui.querySelector("#attr-editor").onmouseenter = function (event) {
if (this.timerId) if (this.timerId) {
{
clearTimeout(this.timerId); clearTimeout(this.timerId);
this.timerId = null; this.timerId = null;
} }
event.target.querySelector("#attr-selector").style.display=""; event.target.querySelector("#attr-selector").style.display = "";
}; };
this.ui.querySelector("#attr-editor").onmouseleave = function (event) {
this.ui.querySelector("#attr-editor").onmouseleave=function(event){
let ui = event.target.querySelector("#attr-selector"); let ui = event.target.querySelector("#attr-selector");
this.timerId = setTimeout(()=>{ this.timerId = setTimeout(() => {
ui.style.display="none"; ui.style.display = "none";
this.timerId = null; this.timerId = null;
}, }, 200);
200);
}; };
this.ui.querySelector("#label-more").onmouseenter=function(event){ this.ui.querySelector("#label-more").onmouseenter = function (event) {
if (this.timerId) if (this.timerId) {
{
clearTimeout(this.timerId); clearTimeout(this.timerId);
this.timerId = null; this.timerId = null;
} }
let ui = event.target.querySelector("#object-dropdown-menu"); let ui = event.target.querySelector("#object-dropdown-menu");
ui.style.display="inherit"; ui.style.display = "inherit";
ui.style.top = "100%"; ui.style.top = "100%";
ui.style.left = "0%"; ui.style.left = "0%";
ui.style.right = null; ui.style.right = null;
ui.style.bottom = null; ui.style.bottom = null;
let rect = ui.getClientRects()[0]; let rect = ui.getClientRects()[0];
if (window.innerHeight < rect.y+rect.height) if (window.innerHeight < rect.y + rect.height) {
{
ui.style.top = null; ui.style.top = null;
ui.style.bottom = "100%"; ui.style.bottom = "100%";
} }
if (window.innerWidth < rect.x+rect.width) if (window.innerWidth < rect.x + rect.width) {
{
ui.style.left = null; ui.style.left = null;
ui.style.right = "0%"; ui.style.right = "0%";
} }
}; };
this.ui.querySelector("#label-more").onmouseleave=function(event){ this.ui.querySelector("#label-more").onmouseleave = function (event) {
let ui = event.target.querySelector("#object-dropdown-menu"); let ui = event.target.querySelector("#object-dropdown-menu");
this.timerId = setTimeout(()=>{ this.timerId = setTimeout(() => {
ui.style.display="none"; ui.style.display = "none";
this.timerId = null; this.timerId = null;
}, }, 200);
200);
}; };
let dropdownMenu = this.ui.querySelector("#object-dropdown-menu"); let dropdownMenu = this.ui.querySelector("#object-dropdown-menu");
for (let i = 0; i < dropdownMenu.children.length; i++) for (let i = 0; i < dropdownMenu.children.length; i++) {
{ dropdownMenu.children[i].onclick = (event) => {
dropdownMenu.children[i].onclick = (event) =>
{
//event.preventDefault(); //event.preventDefault();
event.stopPropagation(); event.stopPropagation();
this.eventHandler(event); this.eventHandler(event);
this.ui.querySelector("#object-dropdown-menu").style.display="none"; this.ui.querySelector("#object-dropdown-menu").style.display = "none";
} };
} }
} }
hide() hide() {
{
this.ui.style.display = "none"; this.ui.style.display = "none";
} }
show() show() {
{
this.ui.style.display = "inline-block"; this.ui.style.display = "inline-block";
this.ui.querySelector("#attr-selector").style.display="none"; this.ui.querySelector("#attr-selector").style.display = "none";
} }
setValue(obj_type, obj_track_id, obj_attr) {
setValue(obj_type, obj_track_id, obj_attr){
this.ui.querySelector("#object-category-selector").value = obj_type; this.ui.querySelector("#object-category-selector").value = obj_type;
this.setAttrOptions(obj_type, obj_attr); this.setAttrOptions(obj_type, obj_attr);
this.ui.querySelector("#object-track-id-editor").value = obj_track_id; this.ui.querySelector("#object-track-id-editor").value = obj_track_id;
if (obj_attr) if (obj_attr) this.ui.querySelector("#attr-input").value = obj_attr;
this.ui.querySelector("#attr-input").value = obj_attr; else this.ui.querySelector("#attr-input").value = "";
else
this.ui.querySelector("#attr-input").value = "";
} }
setPos(pos) setPos(pos) {
{ if (pos) {
if (pos)
{
this.ui.style.top = pos.top; this.ui.style.top = pos.top;
this.ui.style.left = pos.left; this.ui.style.left = pos.left;
} }
} }
setAttrOptions(obj_type, obj_attr) setAttrOptions(obj_type, obj_attr) {
{
let attrs = ["static"]; let attrs = ["static"];
if (
if (globalObjectCategory.obj_type_map[obj_type] && globalObjectCategory.obj_type_map[obj_type].attr) globalObjectCategory.obj_type_map[obj_type] &&
globalObjectCategory.obj_type_map[obj_type].attr
)
attrs = attrs.concat(globalObjectCategory.obj_type_map[obj_type].attr); attrs = attrs.concat(globalObjectCategory.obj_type_map[obj_type].attr);
// merge attrs // merge attrs
let objAttrs = []; let objAttrs = [];
if (obj_attr){ if (obj_attr) {
objAttrs = obj_attr.split(",").map(a=>a.trim()); objAttrs = obj_attr.split(",").map((a) => a.trim());
objAttrs.forEach(a=>{ objAttrs.forEach((a) => {
if (!attrs.find(x=>x==a)) if (!attrs.find((x) => x == a)) {
{
attrs.push(a); attrs.push(a);
} }
}) });
} }
let items = ``; let items = ``;
attrs.forEach((a) => {
attrs.forEach(a=>{ if (objAttrs.find((x) => x == a)) {
if (objAttrs.find(x=>x==a)){ items += `<div class='attr-item attr-selected'>${a}</div>`;
items+= `<div class='attr-item attr-selected'>${a}</div>` } else {
} items += `<div class='attr-item'>${a}</div>`;
else {
items+= `<div class='attr-item'>${a}</div>`
} }
}); });
this.ui.querySelector("#attr-selector").innerHTML = items; this.ui.querySelector("#attr-selector").innerHTML = items;
this.ui.querySelector("#attr-selector").onclick = (event)=>{ this.ui.querySelector("#attr-selector").onclick = (event) => {
let attrs = this.ui.querySelector("#attr-input").value; let attrs = this.ui.querySelector("#attr-input").value;
let objCurrentAttrs = []; let objCurrentAttrs = [];
if (attrs) if (attrs) objCurrentAttrs = attrs.split(",").map((a) => a.trim());
objCurrentAttrs = attrs.split(",").map(a=>a.trim());
let clickedAttr = event.target.innerText; let clickedAttr = event.target.innerText;
if (objCurrentAttrs.find(x=>x==clickedAttr)) if (objCurrentAttrs.find((x) => x == clickedAttr)) {
{ objCurrentAttrs = objCurrentAttrs.filter((x) => x != clickedAttr);
objCurrentAttrs = objCurrentAttrs.filter(x => x!= clickedAttr); event.target.className = "attr-item";
event.target.className = 'attr-item'; } else {
}
else
{
objCurrentAttrs.push(clickedAttr); objCurrentAttrs.push(clickedAttr);
event.target.className = 'attr-item attr-selected'; event.target.className = "attr-item attr-selected";
} }
attrs = ""; attrs = "";
if (objCurrentAttrs.length > 0) if (objCurrentAttrs.length > 0) {
{ attrs = objCurrentAttrs.reduce((a, b) => a + (a ? "," : "") + b);
attrs = objCurrentAttrs.reduce((a,b)=>a+ (a?",":"") + b);
} }
this.ui.querySelector("#attr-input").value = attrs; this.ui.querySelector("#attr-input").value = attrs;
this.eventHandler({ this.eventHandler({
currentTarget:{ currentTarget: {
id: "attr-input", id: "attr-input",
value: attrs value: attrs,
} },
}); });
};
}
} }
installEventHandler(){ installEventHandler() {
let btns = [ let btns = [
"#label-del", "#label-del",
"#label-gen-id", "#label-gen-id",
@ -216,56 +177,59 @@ class FastToolBox{
"#label-rotate", "#label-rotate",
]; ];
btns.forEach(btn=>{ btns.forEach((btn) => {
this.ui.querySelector(btn).onclick = (event)=>{ this.ui.querySelector(btn).onclick = (event) => {
this.eventHandler(event); this.eventHandler(event);
}; };
}); });
this.ui.querySelector("#object-category-selector").onchange = event=>{ this.ui.querySelector("#object-category-selector").onchange = (event) => {
//this.ui.querySelector("#attr-input").value=""; //this.ui.querySelector("#attr-input").value="";
this.setAttrOptions(event.currentTarget.value, this.ui.querySelector("#attr-input").value); this.setAttrOptions(
event.currentTarget.value,
this.ui.querySelector("#attr-input").value
);
this.eventHandler(event); this.eventHandler(event);
}; };
this.ui.querySelector("#object-track-id-editor").onchange = (event) =>
this.ui.querySelector("#object-track-id-editor").onchange = event=>this.eventHandler(event); this.eventHandler(event);
this.ui.querySelector("#object-track-id-editor").addEventListener("keydown", e=>e.stopPropagation()); this.ui
this.ui.querySelector("#object-track-id-editor").addEventListener("keyup", event=>{ .querySelector("#object-track-id-editor")
.addEventListener("keydown", (e) => e.stopPropagation());
this.ui
.querySelector("#object-track-id-editor")
.addEventListener("keyup", (event) => {
event.stopPropagation(); event.stopPropagation();
this.eventHandler(event); this.eventHandler(event);
}); });
this.ui.querySelector("#attr-input").onchange = event=>this.eventHandler(event); this.ui.querySelector("#attr-input").onchange = (event) =>
this.ui.querySelector("#attr-input").addEventListener("keydown", e=>e.stopPropagation()); this.eventHandler(event);
this.ui.querySelector("#attr-input").addEventListener("keyup", event=>{ this.ui
.querySelector("#attr-input")
.addEventListener("keydown", (e) => e.stopPropagation());
this.ui.querySelector("#attr-input").addEventListener("keyup", (event) => {
event.stopPropagation(); event.stopPropagation();
this.eventHandler(event); this.eventHandler(event);
}); });
} }
} }
class FloatLabelManager { class FloatLabelManager {
id_enabled = true; id_enabled = true;
category_enabled = true; category_enabled = true;
color_scheme = "category"; color_scheme = "category";
constructor(editor_ui, container_div, view, func_on_label_clicked) constructor(editor_ui, container_div, view, func_on_label_clicked) {
{
this.view = view; //access camera by view, since camera is dynamic this.view = view; //access camera by view, since camera is dynamic
this.editor_ui = editor_ui; this.editor_ui = editor_ui;
this.container = container_div; this.container = container_div;
this.labelsUi = editor_ui.querySelector("#floating-labels"); this.labelsUi = editor_ui.querySelector("#floating-labels");
this.floatingUi = editor_ui.querySelector("#floating-things"); this.floatingUi = editor_ui.querySelector("#floating-things");
this.style = document.createElement("style");
this.temp_style = document.createElement("style");
this.style = document.createElement('style');
this.temp_style = document.createElement('style');
this.on_label_clicked = func_on_label_clicked; this.on_label_clicked = func_on_label_clicked;
document.head.appendChild(this.style); document.head.appendChild(this.style);
@ -275,57 +239,50 @@ class FloatLabelManager {
this.category_enabled = !pointsGlobalConfig.hideCategory; this.category_enabled = !pointsGlobalConfig.hideCategory;
} }
hide(){ hide() {
this.floatingUi.style.display="none"; this.floatingUi.style.display = "none";
} }
show(){ show() {
this.floatingUi.style.display=""; this.floatingUi.style.display = "";
} }
show_id(show) {
show_id(show){
this.id_enabled = show; this.id_enabled = show;
if (!show){ if (!show) {
this.temp_style.sheet.insertRule(".label-obj-id-text {display: none}"); this.temp_style.sheet.insertRule(".label-obj-id-text {display: none}");
} } else {
else{ for (let i = this.temp_style.sheet.cssRules.length - 1; i >= 0; i--) {
for (let i = this.temp_style.sheet.cssRules.length-1; i >= 0; i--){
var r = this.temp_style.sheet.cssRules[i]; var r = this.temp_style.sheet.cssRules[i];
if (r.selectorText === ".label-obj-id-text"){ if (r.selectorText === ".label-obj-id-text") {
this.temp_style.sheet.deleteRule(i); this.temp_style.sheet.deleteRule(i);
} }
} }
} }
} }
show_category(show){ show_category(show) {
this.category_enabled = show; this.category_enabled = show;
if (!show){ if (!show) {
this.temp_style.sheet.insertRule(".label-obj-type-text {display: none}"); this.temp_style.sheet.insertRule(".label-obj-type-text {display: none}");
this.temp_style.sheet.insertRule(".label-obj-attr-text {display: none}"); this.temp_style.sheet.insertRule(".label-obj-attr-text {display: none}");
} } else {
else{ for (let i = this.temp_style.sheet.cssRules.length - 1; i >= 0; i--) {
for (let i = this.temp_style.sheet.cssRules.length-1; i >= 0; i--){
var r = this.temp_style.sheet.cssRules[i]; var r = this.temp_style.sheet.cssRules[i];
if (r.selectorText === ".label-obj-type-text" || r.selectorText === ".label-obj-attr-text"){ if (
r.selectorText === ".label-obj-type-text" ||
r.selectorText === ".label-obj-attr-text"
) {
this.temp_style.sheet.deleteRule(i); this.temp_style.sheet.deleteRule(i);
} }
} }
} }
} }
// hide all temporarily when zoom in one object. // hide all temporarily when zoom in one object.
hide_all(){ hide_all() {
// if (this.temp_style.sheet.cssRules.length == 0){ // if (this.temp_style.sheet.cssRules.length == 0){
// this.temp_style.sheet.insertRule(".label-obj-id-text {display: none}"); // this.temp_style.sheet.insertRule(".label-obj-id-text {display: none}");
// this.temp_style.sheet.insertRule(".label-obj-type-text {display: none}"); // this.temp_style.sheet.insertRule(".label-obj-type-text {display: none}");
@ -334,55 +291,48 @@ class FloatLabelManager {
this.labelsUi.style.display = "none"; this.labelsUi.style.display = "none";
} }
restore_all(){ restore_all() {
// this.show_category(this.category_enabled); // this.show_category(this.category_enabled);
// this.show_id(this.id_enabled); // this.show_id(this.id_enabled);
this.labelsUi.style.display = ""; this.labelsUi.style.display = "";
} }
remove_all_labels(){ remove_all_labels() {
var _self = this; var _self = this;
if (this.labelsUi.children.length>0){ if (this.labelsUi.children.length > 0) {
for (var c=this.labelsUi.children.length-1; c >= 0; c--){ for (var c = this.labelsUi.children.length - 1; c >= 0; c--) {
this.labelsUi.children[c].remove(); this.labelsUi.children[c].remove();
} }
} }
} }
update_all_position() {
update_all_position(){ if (this.labelsUi.children.length > 0) {
if (this.labelsUi.children.length>0){ for (var c = 0; c < this.labelsUi.children.length; c++) {
for (var c=0; c < this.labelsUi.children.length; c++){
var element = this.labelsUi.children[c]; var element = this.labelsUi.children[c];
var best_pos = this.compute_best_position(element.vertices); var best_pos = this.compute_best_position(element.vertices);
var pos = this.coord_to_pixel(best_pos); var pos = this.coord_to_pixel(best_pos);
element.style.top = Math.round(pos.y) + 'px'; element.style.top = Math.round(pos.y) + "px";
element.style.left = Math.round(pos.x) + 'px'; element.style.left = Math.round(pos.x) + "px";
element.className = element.orgClassName; element.className = element.orgClassName;
if (pos.out_view){ if (pos.out_view) {
element.className += " label-out-view"; element.className += " label-out-view";
} }
} }
} }
} }
getLabelEditorPos(local_id) getLabelEditorPos(local_id) {
{ let label = this.editor_ui.querySelector("#obj-local-" + local_id);
let label = this.editor_ui.querySelector("#obj-local-"+local_id); if (label) {
if (label)
{
// if label is hidden, we can't use its pos directly. // if label is hidden, we can't use its pos directly.
let best_pos = this.compute_best_position(label.vertices); let best_pos = this.compute_best_position(label.vertices);
let pos = this.coord_to_pixel(best_pos); let pos = this.coord_to_pixel(best_pos);
return { return {
top: Math.round(pos.y) + label.offsetHeight + "px", top: Math.round(pos.y) + label.offsetHeight + "px",
left: Math.round(pos.x) + 30 + "px", left: Math.round(pos.x) + 30 + "px",
@ -390,30 +340,28 @@ class FloatLabelManager {
} }
} }
set_object_type(local_id, obj_type) {
set_object_type(local_id, obj_type){ var label = this.editor_ui.querySelector("#obj-local-" + local_id);
var label = this.editor_ui.querySelector("#obj-local-"+local_id); if (label) {
if (label){
label.obj_type = obj_type; label.obj_type = obj_type;
label.update_text(); label.update_text();
this.update_color(label); this.update_color(label);
} }
} }
set_object_attr(local_id, obj_attr){ set_object_attr(local_id, obj_attr) {
var label = this.editor_ui.querySelector("#obj-local-"+local_id); var label = this.editor_ui.querySelector("#obj-local-" + local_id);
if (label){ if (label) {
label.obj_attr = obj_attr; label.obj_attr = obj_attr;
label.update_text(); label.update_text();
this.update_color(label); this.update_color(label);
} }
} }
set_object_track_id(local_id, track_id) {
var label = this.editor_ui.querySelector("#obj-local-" + local_id);
set_object_track_id(local_id, track_id){ if (label) {
var label = this.editor_ui.querySelector("#obj-local-"+local_id);
if (label){
label.obj_track_id = track_id; label.obj_track_id = track_id;
label.update_text(); label.update_text();
this.update_color(label); this.update_color(label);
@ -422,9 +370,10 @@ class FloatLabelManager {
translate_vertices_to_global(world, vertices) { translate_vertices_to_global(world, vertices) {
let ret = []; let ret = [];
for (let i = 0; i< vertices.length; i+=4) for (let i = 0; i < vertices.length; i += 4) {
{ let p = new THREE.Vector4()
let p = new THREE.Vector4().fromArray(vertices, i).applyMatrix4(world.webglGroup.matrix); .fromArray(vertices, i)
.applyMatrix4(world.webglGroup.matrix);
ret.push(p.x); ret.push(p.x);
ret.push(p.y); ret.push(p.y);
ret.push(p.z); ret.push(p.z);
@ -432,85 +381,76 @@ class FloatLabelManager {
} }
return ret; return ret;
} }
update_position(box, refresh){ update_position(box, refresh) {
var label = this.editor_ui.querySelector("#obj-local-"+box.obj_local_id); var label = this.editor_ui.querySelector("#obj-local-" + box.obj_local_id);
if (label){
label.vertices = this.translate_vertices_to_global(box.world, psr_to_xyz(box.position, box.scale, box.rotation)); if (label) {
label.vertices = this.translate_vertices_to_global(
box.world,
psr_to_xyz(box.position, box.scale, box.rotation)
);
if (refresh){ if (refresh) {
var best_pos = this.compute_best_position(label.vertices); var best_pos = this.compute_best_position(label.vertices);
var pos = this.coord_to_pixel(best_pos); var pos = this.coord_to_pixel(best_pos);
label.style.top = Math.round(pos.y) + 'px'; label.style.top = Math.round(pos.y) + "px";
label.style.left = Math.round(pos.x) + 'px'; label.style.left = Math.round(pos.x) + "px";
label.className = label.orgClassName; label.className = label.orgClassName;
if (pos.out_view){ if (pos.out_view) {
label.className += " label-out-view"; label.className += " label-out-view";
} }
} }
} }
} }
remove_box(box) {
var label = this.editor_ui.querySelector("#obj-local-" + box.obj_local_id);
if (label) label.remove();
remove_box(box){
var label = this.editor_ui.querySelector("#obj-local-"+box.obj_local_id);
if (label)
label.remove();
} }
set_color_scheme(color_scheme){ set_color_scheme(color_scheme) {
this.color_scheme = color_scheme; this.color_scheme = color_scheme;
} }
update_color(label) update_color(label) {
{ if (this.color_scheme == "id") {
if (this.color_scheme == "id") label.className = "float-label color-" + (label.obj_track_id % 33);
{ } // by id
label.className = "float-label color-"+ (label.obj_track_id % 33); else {
} label.className = "float-label " + label.obj_type;
else // by id
{
label.className = "float-label "+label.obj_type;
} }
label.orgClassName = label.className; label.orgClassName = label.className;
} }
add_label(box){ add_label(box) {
var label = document.createElement("div");
var label = document.createElement('div');
label.id = "obj-local-"+box.obj_local_id; label.id = "obj-local-" + box.obj_local_id;
var _self =this; var _self = this;
label.update_text = function(){ label.update_text = function () {
let label_text = '<div class="label-obj-type-text">'; let label_text = '<div class="label-obj-type-text">';
label_text += this.obj_type; label_text += this.obj_type;
label_text += '</div>'; label_text += "</div>";
if (this.obj_attr) if (this.obj_attr) {
{
label_text += '<div class="label-obj-attr-text">'; label_text += '<div class="label-obj-attr-text">';
label_text += this.obj_attr; label_text += this.obj_attr;
label_text += '</div>'; label_text += "</div>";
} }
label_text += '<div class="label-obj-id-text">'; label_text += '<div class="label-obj-id-text">';
label_text += this.obj_track_id; label_text += this.obj_track_id;
label_text += '</div>'; label_text += "</div>";
this.innerHTML = label_text; this.innerHTML = label_text;
} };
label.obj_type = box.obj_type; label.obj_type = box.obj_type;
label.obj_local_id = box.obj_local_id; label.obj_local_id = box.obj_local_id;
@ -519,74 +459,87 @@ class FloatLabelManager {
label.update_text(); label.update_text();
this.update_color(label); this.update_color(label);
label.vertices = this.translate_vertices_to_global(box.world, psr_to_xyz(box.position, box.scale, box.rotation)); label.vertices = this.translate_vertices_to_global(
box.world,
psr_to_xyz(box.position, box.scale, box.rotation)
);
var best_pos = this.compute_best_position(label.vertices); var best_pos = this.compute_best_position(label.vertices);
best_pos = this.coord_to_pixel(best_pos); best_pos = this.coord_to_pixel(best_pos);
var pos = best_pos; var pos = best_pos;
label.style.top = Math.round(pos.y) + 'px'; label.style.top = Math.round(pos.y) + "px";
label.style.left = Math.round(pos.x) + 'px'; label.style.left = Math.round(pos.x) + "px";
if (pos.out_view){ if (pos.out_view) {
label.className += " label-out-view"; label.className += " label-out-view";
} }
this.labelsUi.appendChild(label); this.labelsUi.appendChild(label);
let self = this; let self = this;
label.onclick = ()=>{ label.onclick = () => {
this.on_label_clicked(box); this.on_label_clicked(box);
}; };
} }
coord_to_pixel(p) {
coord_to_pixel(p){ var width = this.container.clientWidth,
var width = this.container.clientWidth, height = this.container.clientHeight; height = this.container.clientHeight;
var widthHalf = width / 2, heightHalf = height / 2; var widthHalf = width / 2,
heightHalf = height / 2;
var ret={
x: ( p.x * widthHalf ) + widthHalf + 10, var ret = {
y: - ( p.y * heightHalf ) + heightHalf - 10, x: p.x * widthHalf + widthHalf + 10,
out_view: p.x>0.9 || p.x<-0.6 || p.y<-0.9 || p.y>0.9 || p.z< -1 || p.z > 1, y: -(p.y * heightHalf) + heightHalf - 10,
out_view:
p.x > 0.9 ||
p.x < -0.6 ||
p.y < -0.9 ||
p.y > 0.9 ||
p.z < -1 ||
p.z > 1,
// p.x<-0.6 to prevent it from appearing ontop of sideviews. // p.x<-0.6 to prevent it from appearing ontop of sideviews.
} };
return ret; return ret;
} }
compute_best_position(vertices){ compute_best_position(vertices) {
var _self = this; var _self = this;
var camera_p = [0,1,2,3,4,5,6,7].map(function(i){ var camera_p = [0, 1, 2, 3, 4, 5, 6, 7].map(function (i) {
return new THREE.Vector3(vertices[i*4+0], vertices[i*4+1], vertices[i*4+2]); return new THREE.Vector3(
vertices[i * 4 + 0],
vertices[i * 4 + 1],
vertices[i * 4 + 2]
);
}); });
camera_p.forEach(function(x){ camera_p.forEach(function (x) {
x.project(_self.view.camera); x.project(_self.view.camera);
}); });
var visible_p = camera_p; var visible_p = camera_p;
var best_p = {x:-1, y: -1, z: -2}; var best_p = { x: -1, y: -1, z: -2 };
visible_p.forEach(function(p){ visible_p.forEach(function (p) {
if (p.x > best_p.x){ if (p.x > best_p.x) {
best_p.x = p.x; best_p.x = p.x;
} }
if (p.y > best_p.y){ if (p.y > best_p.y) {
best_p.y = p.y; best_p.y = p.y;
} }
if (p.z > best_p.z){ if (p.z > best_p.z) {
best_p.z = p.z; best_p.z = p.z;
} }
}) });
return best_p; return best_p;
} }
} }
export { FloatLabelManager, FastToolBox };
export {FloatLabelManager, FastToolBox};

@ -1,9 +1,15 @@
import { CubeRefractionMapping } from "./lib/three.module.js"; import { CubeRefractionMapping } from "./lib/three.module.js";
import {saveWorldList} from "./save.js" import { saveWorldList } from "./save.js";
var Header=function(ui, data, cfg, onSceneChanged, onFrameChanged, onObjectSelected, onCameraChanged){ var Header = function (
ui,
data,
cfg,
onSceneChanged,
onFrameChanged,
onObjectSelected,
onCameraChanged
) {
this.ui = ui; this.ui = ui;
this.data = data; this.data = data;
this.cfg = cfg; this.cfg = cfg;
@ -20,137 +26,167 @@ var Header=function(ui, data, cfg, onSceneChanged, onFrameChanged, onObjectSelec
this.onObjectSelected = onObjectSelected; this.onObjectSelected = onObjectSelected;
this.onCameraChanged = onCameraChanged; this.onCameraChanged = onCameraChanged;
if (cfg.disableSceneSelector) {
if (cfg.disableSceneSelector){ this.sceneSelectorUi.style.display = "none";
this.sceneSelectorUi.style.display="none";
} }
if (cfg.disableFrameSelector){ if (cfg.disableFrameSelector) {
this.frameSelectorUi.style.display="none"; this.frameSelectorUi.style.display = "none";
} }
if (cfg.disableCameraSelector){ if (cfg.disableCameraSelector) {
this.cameraSelectorUi.style.display="none"; this.cameraSelectorUi.style.display = "none";
} }
// update scene selector ui // update scene selector ui
this.updateSceneList = function (sceneDescList) {
this.updateSceneList = function(sceneDescList){
let scene_selector_str = "<option>--scene--</option>"; let scene_selector_str = "<option>--scene--</option>";
for (let scene in sceneDescList) for (let scene in sceneDescList) {
{
if (data.sceneDescList[scene]) if (data.sceneDescList[scene])
scene_selector_str += "<option value="+scene +">"+scene + " - " +data.sceneDescList[scene].scene + "</option>"; scene_selector_str +=
"<option value=" +
scene +
">" +
scene +
" - " +
data.sceneDescList[scene].scene +
"</option>";
else else
scene_selector_str += "<option value="+scene +">"+scene+ "</option>"; scene_selector_str +=
"<option value=" + scene + ">" + scene + "</option>";
} }
this.ui.querySelector("#scene-selector").innerHTML = scene_selector_str; this.ui.querySelector("#scene-selector").innerHTML = scene_selector_str;
} };
this.updateSceneList(this.data.sceneDescList); this.updateSceneList(this.data.sceneDescList);
this.ui.querySelector("#btn-reload-scene-list").onclick = (event)=>{ this.ui.querySelector("#btn-reload-scene-list").onclick = (event) => {
let curentValue = this.sceneSelectorUi.value; let curentValue = this.sceneSelectorUi.value;
this.data.readSceneList().then((sceneDescList=>{ this.data.readSceneList().then((sceneDescList) => {
this.updateSceneList(sceneDescList); this.updateSceneList(sceneDescList);
this.sceneSelectorUi.value = curentValue; this.sceneSelectorUi.value = curentValue;
})) });
} };
this.sceneSelectorUi.onchange = (e)=>{this.onSceneChanged(e);}; this.sceneSelectorUi.onchange = (e) => {
this.objectSelectorUi.onchange = (e)=>{this.onObjectSelected(e);}; this.onSceneChanged(e);
this.frameSelectorUi.onchange = (e)=>{this.onFrameChanged(e);}; };
this.cameraSelectorUi.onchange = (e)=>{this.onCameraChanged(e);}; this.objectSelectorUi.onchange = (e) => {
this.onObjectSelected(e);
};
this.frameSelectorUi.onchange = (e) => {
this.onFrameChanged(e);
};
this.cameraSelectorUi.onchange = (e) => {
this.onCameraChanged(e);
};
this.setObject = function(id) this.setObject = function (id) {
{
this.objectSelectorUi.value = id; this.objectSelectorUi.value = id;
} };
this.clear_box_info = function(){ this.clear_box_info = function () {
this.boxUi.innerHTML = ''; this.boxUi.innerHTML = "";
}; };
this.update_box_info = function(box){ (this.update_box_info = function (box) {
var scale = box.scale; var scale = box.scale;
var pos = box.position; var pos = box.position;
var rotation = box.rotation; var rotation = box.rotation;
var points_number = box.world.lidar.get_box_points_number(box); var points_number = box.world.lidar.get_box_points_number(box);
let distance = Math.sqrt(pos.x*pos.x + pos.y*pos.y).toFixed(2); let distance = Math.sqrt(pos.x * pos.x + pos.y * pos.y).toFixed(2);
this.boxUi.innerHTML = "<span>" + box.obj_type +"-"+box.obj_track_id + this.boxUi.innerHTML =
(box.annotator? ("</span> | <span title='annotator'>" + box.annotator) : "") + "<span>" +
"</span> | <span title='distance'>" + distance + box.obj_type +
"</span> | <span title='position'>"+pos.x.toFixed(2) +" "+pos.y.toFixed(2) + " " + pos.z.toFixed(2) + "-" +
"</span> | <span title='scale'>" +scale.x.toFixed(2) +" "+scale.y.toFixed(2) + " " + scale.z.toFixed(2) + box.obj_track_id +
(box.annotator
? "</span> | <span title='annotator'>" + box.annotator
: "") +
"</span> | <span title='distance'>" +
distance +
"</span> | <span title='position'>" +
pos.x.toFixed(2) +
" " +
pos.y.toFixed(2) +
" " +
pos.z.toFixed(2) +
"</span> | <span title='scale'>" +
scale.x.toFixed(2) +
" " +
scale.y.toFixed(2) +
" " +
scale.z.toFixed(2) +
"</span> | <span title='rotation'>" + "</span> | <span title='rotation'>" +
(rotation.x*180/Math.PI).toFixed(2)+" "+(rotation.y*180/Math.PI).toFixed(2)+" "+(rotation.z*180/Math.PI).toFixed(2)+ ((rotation.x * 180) / Math.PI).toFixed(2) +
" " +
((rotation.y * 180) / Math.PI).toFixed(2) +
" " +
((rotation.z * 180) / Math.PI).toFixed(2) +
"</span> | <span title = 'points'>" + "</span> | <span title = 'points'>" +
points_number + "</span> "; points_number +
if (box.follows){ "</span> ";
this.boxUi.innerHTML += "| F:"+box.follows.obj_track_id; if (box.follows) {
} this.boxUi.innerHTML += "| F:" + box.follows.obj_track_id;
}, }
}),
this.set_ref_obj = function(marked_object){ (this.set_ref_obj = function (marked_object) {
this.refObjUi.innerHTML="| Ref: "+marked_object.scene+"/"+marked_object.frame+": "+marked_object.ann.obj_type+"-"+marked_object.ann.obj_id; this.refObjUi.innerHTML =
}, "| Ref: " +
marked_object.scene +
this.set_frame_info =function(scene, frame, on_scene_changed){ "/" +
marked_object.frame +
if (this.sceneSelectorUi.value != scene){ ": " +
marked_object.ann.obj_type +
"-" +
marked_object.ann.obj_id;
}),
(this.set_frame_info = function (scene, frame, on_scene_changed) {
if (this.sceneSelectorUi.value != scene) {
this.sceneSelectorUi.value = scene; this.sceneSelectorUi.value = scene;
on_scene_changed(scene); on_scene_changed(scene);
} }
this.frameSelectorUi.value = frame; this.frameSelectorUi.value = frame;
}, }),
(this.clear_frame_info = function (scene, frame) {}),
this.clear_frame_info = function(scene, frame){ (this.updateModifiedStatus = function () {
let frames = this.data.worldList.filter((w) => w.annotation.modified);
}, if (frames.length > 0) {
this.ui.querySelector("#changed-mark").className =
this.updateModifiedStatus = function(){ "ui-button alarm-mark";
let frames = this.data.worldList.filter(w=>w.annotation.modified); } else {
if (frames.length > 0) this.ui.querySelector("#changed-mark").className = "ui-button";
{
this.ui.querySelector("#changed-mark").className = 'ui-button alarm-mark';
}
else
{
this.ui.querySelector("#changed-mark").className = 'ui-button';
} }
} });
this.ui.querySelector("#changed-mark").onmouseenter = ()=>{
this.ui.querySelector("#changed-mark").onmouseenter = () => {
let items = ""; let items = "";
let frames = this.data.worldList.filter(w=>w.annotation.modified).map(w=>w.frameInfo); let frames = this.data.worldList
frames.forEach(f=>{ .filter((w) => w.annotation.modified)
items += "<div class='modified-world-item'>" + f.frame + '</div>'; .map((w) => w.frameInfo);
frames.forEach((f) => {
items += "<div class='modified-world-item'>" + f.frame + "</div>";
}); });
if (frames.length > 0){ if (frames.length > 0) {
this.ui.querySelector("#changed-world-list").innerHTML = items; this.ui.querySelector("#changed-world-list").innerHTML = items;
this.ui.querySelector("#changed-world-list-wrapper").style.display = 'inherit'; this.ui.querySelector("#changed-world-list-wrapper").style.display =
} "inherit";
} }
};
this.ui.querySelector("#changed-mark").onmouseleave = ()=>{ this.ui.querySelector("#changed-mark").onmouseleave = () => {
this.ui.querySelector("#changed-world-list-wrapper").style.display = 'none'; this.ui.querySelector("#changed-world-list-wrapper").style.display = "none";
} };
this.ui.querySelector("#save-button").onclick = ()=>{ this.ui.querySelector("#save-button").onclick = () => {
saveWorldList(this.data.worldList); saveWorldList(this.data.worldList);
} };
}; };
export { Header };
export {Header}

File diff suppressed because it is too large Load Diff

@ -1,90 +1,71 @@
import { globalKeyDownManager } from "./keydown_manager.js"; import { globalKeyDownManager } from "./keydown_manager.js";
import { PopupDialog } from "./popup_dialog.js"; import { PopupDialog } from "./popup_dialog.js";
class InfoBox extends PopupDialog {
class InfoBox extends PopupDialog{
mouseDown = false; mouseDown = false;
mouseDwwnPos = {}; mouseDwwnPos = {};
constructor(ui) {
constructor(ui)
{
super(ui); super(ui);
this.contentUi = this.ui.querySelector("#info-content"); this.contentUi = this.ui.querySelector("#info-content");
this.buttons = { this.buttons = {
"yes": this.ui.querySelector("#btn-yes"), yes: this.ui.querySelector("#btn-yes"),
"no": this.ui.querySelector("#btn-no"), no: this.ui.querySelector("#btn-no"),
"maximize": this.ui.querySelector("#btn-maximize"), maximize: this.ui.querySelector("#btn-maximize"),
"restore": this.ui.querySelector("#btn-restore"), restore: this.ui.querySelector("#btn-restore"),
"exit": this.ui.querySelector("#btn-exit"), exit: this.ui.querySelector("#btn-exit"),
}; };
for (let btn in this.buttons) for (let btn in this.buttons) {
{ this.buttons[btn].onclick = () => {
this.buttons[btn].onclick = ()=>{
this.hide(btn); this.hide(btn);
} };
} }
this.ui.addEventListener("keydown", (ev)=>{ this.ui.addEventListener("keydown", (ev) => {
//anykey //anykey
if ( ev.shiftKey || ev.ctrlKey || ev.altKey) if (ev.shiftKey || ev.ctrlKey || ev.altKey) {
{
// //
} } else {
else
{
this.hide(); this.hide();
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
} }
}); });
} }
showButtons(btns) {
for (let btn in this.buttons) {
showButtons(btns){ this.buttons[btn].style.display = "none";
for (let btn in this.buttons)
{
this.buttons[btn].style.display = 'none';
} }
for (let btn in btns) for (let btn in btns) {
{ this.buttons[btns[btn]].style.display = "";
this.buttons[btns[btn]].style.display = '';
} }
} }
makeVisible(pointerPosition) makeVisible(pointerPosition) {
{ if (!pointerPosition) {
if (!pointerPosition)
{
//default pos //default pos
let parentRect = this.ui.getBoundingClientRect(); let parentRect = this.ui.getBoundingClientRect();
let viewRect = this.viewUi.getBoundingClientRect(); let viewRect = this.viewUi.getBoundingClientRect();
this.viewUi.style.top = (parentRect.top+parentRect.height/3) + "px"; this.viewUi.style.top = parentRect.top + parentRect.height / 3 + "px";
this.viewUi.style.left = (parentRect.left+parentRect.width/2-viewRect.width/2) + "px"; this.viewUi.style.left =
} parentRect.left + parentRect.width / 2 - viewRect.width / 2 + "px";
else } else {
{
let parentRect = this.ui.getBoundingClientRect(); let parentRect = this.ui.getBoundingClientRect();
let viewRect = this.viewUi.getBoundingClientRect(); let viewRect = this.viewUi.getBoundingClientRect();
let left = pointerPosition.x - viewRect.width/2; let left = pointerPosition.x - viewRect.width / 2;
if (left < parentRect.left) left = parentRect.left; if (left < parentRect.left) left = parentRect.left;
if (left + viewRect.width > parentRect.right) if (left + viewRect.width > parentRect.right)
left -= left + viewRect.width - parentRect.right; left -= left + viewRect.width - parentRect.right;
let top = pointerPosition.y - viewRect.height/2; let top = pointerPosition.y - viewRect.height / 2;
if (top < parentRect.top) if (top < parentRect.top) top = parentRect.top;
top = parentRect.top;
if (top + viewRect.height > parentRect.bottom) if (top + viewRect.height > parentRect.bottom)
top -= top + viewRect.height - parentRect.bottom; top -= top + viewRect.height - parentRect.bottom;
@ -94,9 +75,7 @@ class InfoBox extends PopupDialog{
} }
} }
show(title, content, btnList, onexit, pointerPosition) {
show(title, content, btnList, onexit, pointerPosition)
{
this.showButtons(btnList); this.showButtons(btnList);
this.titleUi.innerText = title; this.titleUi.innerText = title;
@ -108,8 +87,6 @@ class InfoBox extends PopupDialog{
this.ui.focus(); this.ui.focus();
} }
} }
export { InfoBox };
export {InfoBox};

@ -1,42 +1,30 @@
class KeyDownManager {
class KeyDownManager
{
handlerList = []; handlerList = [];
// return id; // return id;
register(handler, name) register(handler, name) {
{
this.handlerList.push([name, handler]); this.handlerList.push([name, handler]);
console.log("register keydown", name); console.log("register keydown", name);
} }
deregister(name) deregister(name) {
{
console.log("deregister keydown", name); console.log("deregister keydown", name);
this.handlerList = this.handlerList.filter(v=>v[0]!== name); this.handlerList = this.handlerList.filter((v) => v[0] !== name);
} }
constructor() constructor() {
{ document.addEventListener("keydown", (event) => {
document.addEventListener( 'keydown', (event)=>{ for (let i = this.handlerList.length - 1; i >= 0; i--) {
for (let i = this.handlerList.length-1; i >= 0; i--)
{
let ret = this.handlerList[i][1](event); let ret = this.handlerList[i][1](event);
if (!ret) if (!ret) {
{
break; break;
} }
} }
}); });
} }
} }
var globalKeyDownManager = new KeyDownManager(); var globalKeyDownManager = new KeyDownManager();
export{globalKeyDownManager}; export { globalKeyDownManager };

File diff suppressed because it is too large Load Diff

@ -1,16 +1,10 @@
import { PopupDialog } from "./popup_dialog.js"; import { PopupDialog } from "./popup_dialog.js";
class LogWindow extends PopupDialog {
class LogWindow extends PopupDialog{
mouseDown = false; mouseDown = false;
mouseDwwnPos = {}; mouseDwwnPos = {};
constructor(ui, btn) {
constructor(ui, btn)
{
super(ui); super(ui);
this.btn = btn; this.btn = btn;
@ -20,71 +14,85 @@ class LogWindow extends PopupDialog{
this.errorsContentUi = this.ui.querySelector("#content-errors"); this.errorsContentUi = this.ui.querySelector("#content-errors");
this.clearBtn = this.ui.querySelector("#btn-clear"); this.clearBtn = this.ui.querySelector("#btn-clear");
this.clearBtn.onclick = ()=>{ this.logsContentUi.innerHTML = ""; }; this.clearBtn.onclick = () => {
this.logsContentUi.innerHTML = "";
};
this.log("Welcome!"); this.log("Welcome!");
this.logBtn = this.ui.querySelector("#tab-log"); this.logBtn = this.ui.querySelector("#tab-log");
this.errorBtn = this.ui.querySelector("#tab-error"); this.errorBtn = this.ui.querySelector("#tab-error");
this.logBtn.onclick= ()=>{ this.logBtn.onclick = () => {
this.logBtn.className = "tab-button tab-selected"; this.logBtn.className = "tab-button tab-selected";
this.errorBtn.className = "tab-button"; this.errorBtn.className = "tab-button";
this.logsContentUi.style.display = 'inherit'; this.logsContentUi.style.display = "inherit";
this.errorsContentUi.style.display = 'none'; this.errorsContentUi.style.display = "none";
} };
this.errorBtn.onclick= ()=>{ this.errorBtn.onclick = () => {
this.errorBtn.className = "tab-button tab-selected"; this.errorBtn.className = "tab-button tab-selected";
this.logBtn.className = "tab-button"; this.logBtn.className = "tab-button";
this.logsContentUi.style.display = 'none'; this.logsContentUi.style.display = "none";
this.errorsContentUi.style.display = 'inherit'; this.errorsContentUi.style.display = "inherit";
} };
} }
setErrorsContent(errors) setErrorsContent(errors) {
{
let summary = `${errors.length} warnings.<br>`; let summary = `${errors.length} warnings.<br>`;
let text = errors.map(r=>`<a class='log-object-frame-id'>${r.frame_id},${r.obj_id}</a>, ${r.desc}<br>`).reduce((a,b)=>a+b, summary); let text = errors
.map(
(r) =>
`<a class='log-object-frame-id'>${r.frame_id},${r.obj_id}</a>, ${r.desc}<br>`
)
.reduce((a, b) => a + b, summary);
this.errorsContentUi.innerHTML = text; this.errorsContentUi.innerHTML = text;
this.errorsContentUi.querySelectorAll(".log-object-frame-id").forEach(ele=>{ this.errorsContentUi
ele.onclick = (event)=>{ .querySelectorAll(".log-object-frame-id")
.forEach((ele) => {
ele.onclick = (event) => {
let obj = event.currentTarget.innerHTML.split(","); let obj = event.currentTarget.innerHTML.split(",");
console.log("click", obj); console.log("click", obj);
window.editor.currentMainEditor.gotoObjectFrame(...obj); //frameid, objid window.editor.currentMainEditor.gotoObjectFrame(...obj); //frameid, objid
} };
}); });
} }
setUi(ui) {}
setUi(ui) show() {
{
}
show()
{
super.show(); super.show();
} }
gettime() { gettime() {
let d = new Date(); let d = new Date();
return "" + d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds(); return (
"" +
d.getFullYear() +
"-" +
(d.getMonth() + 1) +
"-" +
d.getDate() +
" " +
d.getHours() +
":" +
d.getMinutes() +
":" +
d.getSeconds()
);
} }
autoScroll = true; autoScroll = true;
updateAutoScrollFlag() updateAutoScrollFlag() {
{
let div = this.logsContentUi; let div = this.logsContentUi;
this.autoScroll = (div.scrollHeight-10 < div.scrollTop + div.clientHeight); this.autoScroll = div.scrollHeight - 10 < div.scrollTop + div.clientHeight;
} }
autoScrollOutput(){ autoScrollOutput() {
let div = this.logsContentUi; let div = this.logsContentUi;
if (this.autoScroll) if (this.autoScroll) div.scrollTop = div.scrollHeight;
div.scrollTop = div.scrollHeight;
} }
isInt(n) { isInt(n) {
@ -95,7 +103,10 @@ class LogWindow extends PopupDialog{
let thisstr = ""; let thisstr = "";
for (let i in args) { for (let i in args) {
if (typeof args[i] == "number") { if (typeof args[i] == "number") {
thisstr += " <span class='number'>" + (isInt(args[i]) ? args[i] : args[i].toFixed(6)) + "</span>"; thisstr +=
" <span class='number'>" +
(isInt(args[i]) ? args[i] : args[i].toFixed(6)) +
"</span>";
} else if ([".", ",", ":", ";"].find((c) => c == args[i])) { } else if ([".", ",", ":", ";"].find((c) => c == args[i])) {
thisstr += args[i]; thisstr += args[i];
} else { } else {
@ -117,18 +128,23 @@ class LogWindow extends PopupDialog{
this.logid++; this.logid++;
this.logsContentUi.innerHTML =
this.logsContentUi.innerHTML = old_content + "<div id='log-" + this.logid + "' class='" + color + "'>" + thisstr + "</div>"; old_content +
"<div id='log-" +
this.logid +
"' class='" +
color +
"'>" +
thisstr +
"</div>";
this.autoScrollOutput(); this.autoScrollOutput();
} }
logid = 0; logid = 0;
maxLogLength = 10000; // stringLength; maxLogLength = 10000; // stringLength;
log() { log() {
this.svg.style.fill = this.logid % 2 ? "red" : "green";
this.svg.style.fill= this.logid %2 ? "red" : "green";
this.updateAutoScrollFlag(); this.updateAutoScrollFlag();
@ -141,14 +157,14 @@ class LogWindow extends PopupDialog{
this.logid++; this.logid++;
if (old_content.length > this.maxLogLength) if (old_content.length > this.maxLogLength) {
{ old_content = old_content.slice(old_content.length - this.maxLogLength);
old_content = old_content.slice(old_content.length-this.maxLogLength);
let firstLogPos = old_content.search("<div id="); let firstLogPos = old_content.search("<div id=");
old_content = old_content.slice(firstLogPos); old_content = old_content.slice(firstLogPos);
} }
this.logsContentUi.innerHTML = old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>"; this.logsContentUi.innerHTML =
old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>";
this.autoScrollOutput(); this.autoScrollOutput();
} }
@ -179,24 +195,19 @@ class LogWindow extends PopupDialog{
thisstr += this.buildLogStr(arguments); thisstr += this.buildLogStr(arguments);
let laststr = this.logsContentUi.querySelector("#log-" + this.logid); let laststr = this.logsContentUi.querySelector("#log-" + this.logid);
if (laststr && laststr.innerHTML && thisstr == laststr.innerHTML) if (laststr && laststr.innerHTML && thisstr == laststr.innerHTML) return;
return;
this.logid++; this.logid++;
this.logsContentUi.innerHTML = old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>"; this.logsContentUi.innerHTML =
old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>";
this.autoScrollOutput(); this.autoScrollOutput();
} }
} }
let logger = null; let logger = null;
function create_logger(ui, btn){ function create_logger(ui, btn) {
logger = new LogWindow(ui, btn); logger = new LogWindow(ui, btn);
} }
export{logger, create_logger}; export { logger, create_logger };

@ -1,27 +1,22 @@
import{Config} from "./config.js" import { Config } from "./config.js";
import{Editor} from "./editor.js" import { Editor } from "./editor.js";
import {Data} from './data.js' import { Data } from "./data.js";
let pointsGlobalConfig = new Config(); let pointsGlobalConfig = new Config();
window.pointsGlobalConfig = pointsGlobalConfig; window.pointsGlobalConfig = pointsGlobalConfig;
pointsGlobalConfig.load(); pointsGlobalConfig.load();
document.documentElement.className = "theme-" + pointsGlobalConfig.theme;
document.documentElement.className="theme-"+pointsGlobalConfig.theme; document.body.addEventListener("keydown", (event) => {
if (event.ctrlKey && "asdv".indexOf(event.key) !== -1) {
event.preventDefault();
document.body.addEventListener('keydown', event => {
if (event.ctrlKey && 'asdv'.indexOf(event.key) !== -1) {
event.preventDefault()
} }
}); });
async function createMainEditor(){ async function createMainEditor() {
let template = document.querySelector("#editor-template");
let template = document.querySelector('#editor-template');
let maindiv = document.querySelector("#main-editor"); let maindiv = document.querySelector("#main-editor");
let main_ui = template.content.cloneNode(true); let main_ui = template.content.cloneNode(true);
maindiv.appendChild(main_ui); // input parameter is changed after `append` maindiv.appendChild(main_ui); // input parameter is changed after `append`
@ -33,32 +28,30 @@ async function createMainEditor(){
let data = new Data(dataCfg); let data = new Data(dataCfg);
await data.init(); await data.init();
let editor = new Editor(maindiv.lastElementChild, maindiv, editorCfg, data, "main-editor") let editor = new Editor(
maindiv.lastElementChild,
maindiv,
editorCfg,
data,
"main-editor"
);
window.editor = editor; window.editor = editor;
editor.run(); editor.run();
return editor; return editor;
} }
async function start(){ async function start() {
let mainEditor = await createMainEditor(); let mainEditor = await createMainEditor();
let url_string = window.location.href;
let url_string = window.location.href
let url = new URL(url_string); let url = new URL(url_string);
//language //language
let scene = url.searchParams.get("scene"); let scene = url.searchParams.get("scene");
let frame = url.searchParams.get("frame"); let frame = url.searchParams.get("frame");
if (scene && frame) if (scene && frame) {
{
mainEditor.load_world(scene, frame); mainEditor.load_world(scene, frame);
} }
} }
start(); start();

@ -1,62 +1,58 @@
import { logger } from "./log.js"; import { logger } from "./log.js";
import {matmul, euler_angle_to_rotate_matrix_3by3, transpose, matmul2} from "./util.js" import {
matmul,
euler_angle_to_rotate_matrix_3by3,
transpose,
matmul2,
} from "./util.js";
const annMath = { const annMath = {
sub: function (a, b) {
sub: function(a,b){ //pos, rot, scale //pos, rot, scale
let c = []; let c = [];
for (let i in a) for (let i in a) {
{
c[i] = a[i] - b[i]; c[i] = a[i] - b[i];
} }
return this.norm(c); return this.norm(c);
}, },
div: function(a, d){ // d is scalar div: function (a, d) {
// d is scalar
let c = []; let c = [];
for (let i in a) for (let i in a) {
{ c[i] = a[i] / d;
c[i] = a[i]/d;
} }
return c; return c;
}, },
add: function(a, b){ add: function (a, b) {
let c = []; let c = [];
for (let i in a) for (let i in a) {
{
c[i] = a[i] + b[i]; c[i] = a[i] + b[i];
} }
return this.norm(c); return this.norm(c);
}, },
mul: function(a, d) // d is scalar mul: function (
{ a,
d // d is scalar
) {
let c = []; let c = [];
for (let i in a) for (let i in a) {
{ c[i] = a[i] * d;
c[i] = a[i]*d;
} }
return this.norm(c); return this.norm(c);
}, },
norm: function(c) norm: function (c) {
{ for (let i = 3; i < 6; i++) {
for (let i = 3; i< 6; i++) if (c[i] > Math.PI) {
{
if (c[i] > Math.PI)
{
c[i] -= Math.PI * 2; c[i] -= Math.PI * 2;
} } else if (c[i] < -Math.PI) {
else if (c[i] < - Math.PI)
{
c[i] += Math.PI * 2; c[i] += Math.PI * 2;
} }
} }
@ -64,92 +60,94 @@ const annMath = {
return c; return c;
}, },
normAngle: function (a){ normAngle: function (a) {
if (a > Math.PI) if (a > Math.PI) {
{
return a - Math.PI * 2; return a - Math.PI * 2;
} } else if (a < -Math.PI) {
else if (a < - Math.PI)
{
return a + Math.PI * 2; return a + Math.PI * 2;
} }
return a; return a;
}, },
eleMul: function(a,b) //element-wise multiplication eleMul: function (
{ a,
b //element-wise multiplication
) {
let c = []; let c = [];
for (let i in a) for (let i in a) {
{
c[i] = a[i] * b[i]; c[i] = a[i] * b[i];
} }
return c; return c;
} },
}; };
var ml = { var ml = {
backend: tf.getBackend(), backend: tf.getBackend(),
calibrate_axes: function(points){ calibrate_axes: function (points) {
console.log("backend of tensorflow:", tf.getBackend()); console.log("backend of tensorflow:", tf.getBackend());
console.log("number of points:", points.count); console.log("number of points:", points.count);
var center_points = {}; var center_points = {};
for (var i = 0; i<points.count; i++){ for (var i = 0; i < points.count; i++) {
if (points.array[i*3] < 10 && points.array[i*3]>-10 && if (
points.array[i*3+1] < 10 && points.array[i*3+1]>-10) // x,y in [-10,10] points.array[i * 3] < 10 &&
{ points.array[i * 3] > -10 &&
var key = (10 + Math.round(points.array[i*3]))*100 + (Math.round(points.array[i*3+1])+10); points.array[i * 3 + 1] < 10 &&
if (center_points[key]){ points.array[i * 3 + 1] > -10
) {
// x,y in [-10,10]
var key =
(10 + Math.round(points.array[i * 3])) * 100 +
(Math.round(points.array[i * 3 + 1]) + 10);
if (center_points[key]) {
// save only minimal index // save only minimal index
if (points.array[i*3+2] < points.array[center_points[key]*3+2]){ if (
points.array[i * 3 + 2] < points.array[center_points[key] * 3 + 2]
) {
center_points[key] = i; center_points[key] = i;
} }
} else {
}else {
center_points[key] = i; center_points[key] = i;
} }
} }
} }
var center_point_indices = []; var center_point_indices = [];
for (var i in center_points){ for (var i in center_points) {
center_point_indices.push(center_points[i]); center_point_indices.push(center_points[i]);
} }
//console.log(center_point_indices); //console.log(center_point_indices);
var points_2d = center_point_indices.map(i => [points.array[i*3],points.array[i*3+1],points.array[i*3+2]]); var points_2d = center_point_indices.map((i) => [
var points_array = points_2d.flatMap(x=> x); points.array[i * 3],
points.array[i * 3 + 1],
points.array[i * 3 + 2],
var sum = points_2d.reduce(function(s, x){ ]);
return [s[0] + x[0], var points_array = points_2d.flatMap((x) => x);
s[1] + x[1],
s[2] + x[2]]; var sum = points_2d.reduce(
},[0,0,0]); function (s, x) {
return [s[0] + x[0], s[1] + x[1], s[2] + x[2]];
},
[0, 0, 0]
);
var count = points_2d.length; var count = points_2d.length;
var mean = [sum[0]/count, sum[1]/count, sum[2]/count]; var mean = [sum[0] / count, sum[1] / count, sum[2] / count];
var data_centered = points_2d.map(function(x){
return [
x[0] - mean[0],
x[1] - mean[1],
x[2] - mean[2],
];
})
var normal_v = this.train(data_centered);
var data_centered = points_2d.map(function (x) {
return [x[0] - mean[0], x[1] - mean[1], x[2] - mean[2]];
});
var normal_v = this.train(data_centered);
data.world.add_line(mean, [-normal_v[0]*10, -normal_v[1]*10, normal_v[2]*10]); data.world.add_line(mean, [
-normal_v[0] * 10,
-normal_v[1] * 10,
normal_v[2] * 10,
]);
data.world.lidar.reset_points(points_array); data.world.lidar.reset_points(points_array);
/* /*
@ -163,19 +161,18 @@ var ml = {
//data.world.lidar.update_points_color(); //data.world.lidar.update_points_color();
*/ */
return center_point_indices; return center_point_indices;
}, },
train: function(data_centered) // data is ?*3 array. train: function (
{ data_centered // data is ?*3 array.
) {
var XY = data_centered.map(function (x) {
return x.slice(0, 2);
var XY = data_centered.map(function(x){return x.slice(0,2);}); });
var Z = data_centered.map(function(x){return x[2];}); var Z = data_centered.map(function (x) {
return x[2];
});
var x = tf.tensor2d(XY); var x = tf.tensor2d(XY);
var para = tf.variable(tf.tensor2d([[Math.random(), Math.random()]])); var para = tf.variable(tf.tensor2d([[Math.random(), Math.random()]]));
@ -183,8 +180,8 @@ var ml = {
const learningRate = 0.00001; const learningRate = 0.00001;
const optimizer = tf.train.sgd(learningRate); const optimizer = tf.train.sgd(learningRate);
para.print(); para.print();
for (var i=0; i<20; i++){ for (var i = 0; i < 20; i++) {
optimizer.minimize(function() { optimizer.minimize(function () {
var dists = tf.matMul(para, x.transpose()); var dists = tf.matMul(para, x.transpose());
var sqrdiff = tf.squaredDifference(dists, Z); var sqrdiff = tf.squaredDifference(dists, Z);
var loss = tf.div(tf.sum(sqrdiff), sqrdiff.shape[0]); var loss = tf.div(tf.sum(sqrdiff), sqrdiff.shape[0]);
@ -199,13 +196,9 @@ var ml = {
var pv = para.dataSync(); var pv = para.dataSync();
console.log("train result: ", pv); console.log("train result: ", pv);
return [pv[0], pv[1], 1]; return [pv[0], pv[1], 1];
} },
,
// data is N*2 matrix, // data is N*2 matrix,
l_shape_fit: function(data){ l_shape_fit: function (data) {
// cos, sin // cos, sin
// -sin, cos // -sin, cos
var A = tf.tensor2d(data); var A = tf.tensor2d(data);
@ -214,10 +207,10 @@ var ml = {
var theta = []; var theta = [];
var min = 0; var min = 0;
var min_index = 0; var min_index = 0;
for (var i =0; i<=90; i+=1){ for (var i = 0; i <= 90; i += 1) {
var obj = cal_objetive(A, i); var obj = cal_objetive(A, i);
if (min==0 || min > obj){ if (min == 0 || min > obj) {
min_index = i; min_index = i;
min = obj; min = obj;
} }
@ -228,10 +221,12 @@ var ml = {
//end of func //end of func
function cal_objetive(A, theta){ function cal_objetive(A, theta) {
let r = theta*Math.PI/180; let r = (theta * Math.PI) / 180;
let bases = tf.tensor2d([[Math.cos(r), -Math.sin(r)], let bases = tf.tensor2d([
[Math.sin(r), Math.cos(r)]]); [Math.cos(r), -Math.sin(r)],
[Math.sin(r), Math.cos(r)],
]);
let proj = tf.matMul(A, bases); // n * 2 let proj = tf.matMul(A, bases); // n * 2
let max = tf.max(proj, 0); // 1*2 let max = tf.max(proj, 0); // 1*2
@ -241,13 +236,13 @@ var ml = {
// axis 0 // axis 0
var dist0, dist1; // dist to axis 0, axis 1 var dist0, dist1; // dist to axis 0, axis 1
if (dist_to_min.gather(0).dataSync() < dist_to_max.gather(0).dataSync()){ if (dist_to_min.gather(0).dataSync() < dist_to_max.gather(0).dataSync()) {
dist0 = tf.sub(proj.gather([0], 1), min.gather(0)); dist0 = tf.sub(proj.gather([0], 1), min.gather(0));
} else { } else {
dist0 = tf.sub(max.gather(0), proj.gather([0], 1)); dist0 = tf.sub(max.gather(0), proj.gather([0], 1));
} }
if (dist_to_min.gather(1).dataSync() < dist_to_max.gather(1).dataSync()){ if (dist_to_min.gather(1).dataSync() < dist_to_max.gather(1).dataSync()) {
dist1 = tf.sub(proj.gather([1], 1), min.gather(1)); dist1 = tf.sub(proj.gather([1], 1), min.gather(1));
} else { } else {
dist1 = tf.sub(max.gather(1), proj.gather([1], 1)); dist1 = tf.sub(max.gather(1), proj.gather([1], 1));
@ -257,10 +252,7 @@ var ml = {
var min_dist = tf.concat([dist0, dist1], 1).min(1); var min_dist = tf.concat([dist0, dist1], 1).min(1);
return min_dist.sum().dataSync()[0]; return min_dist.sum().dataSync()[0];
} }
},
}
,
// predict_rotation_cb: function(data, callback){ // predict_rotation_cb: function(data, callback){
// var xhr = new XMLHttpRequest(); // var xhr = new XMLHttpRequest();
// // we defined the xhr // // we defined the xhr
@ -284,82 +276,75 @@ var ml = {
// xhr.send(JSON.stringify({"points": data})); // xhr.send(JSON.stringify({"points": data}));
// }, // },
predict_rotation: function(data){ predict_rotation: function (data) {
const req = new Request("/predict_rotation"); const req = new Request("/predict_rotation");
let init = { let init = {
method: 'POST', method: "POST",
body: JSON.stringify({"points": data}) body: JSON.stringify({ points: data }),
}; };
// we defined the xhr // we defined the xhr
console.log("start predict rotatoin.", data.length, 'points') console.log("start predict rotatoin.", data.length, "points");
return fetch(req, init) return fetch(req, init)
.then(response=>{ .then((response) => {
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
}else{ } else {
console.log("predict rotatoin response received.") console.log("predict rotatoin response received.");
return response.json(); return response.json();
} }
}) })
.catch(reject=>{ .catch((reject) => {
console.log("error predicting yaw angle!"); console.log("error predicting yaw angle!");
}); });
}, },
// autoadj is async // autoadj is async
interpolate_annotation: async function(anns, autoAdj, onFinishOneBox){ interpolate_annotation: async function (anns, autoAdj, onFinishOneBox) {
let i = 0; let i = 0;
while(true){ while (true) {
while (i+1 < anns.length && !(anns[i] && !anns[i+1])){ while (i + 1 < anns.length && !(anns[i] && !anns[i + 1])) {
i++; i++;
} }
let start = i; let start = i;
i+=2; i += 2;
while (i < anns.length && !anns[i]){ while (i < anns.length && !anns[i]) {
i++; i++;
} }
if (i < anns.length){ if (i < anns.length) {
let end = i; let end = i;
// insert (begin, end) // insert (begin, end)
let interpolate_step = annMath.div(annMath.sub(anns[end], anns[start]), (end-start)); let interpolate_step = annMath.div(
annMath.sub(anns[end], anns[start]),
end - start
);
for (let inserti=start+1; inserti<end; inserti++){ for (let inserti = start + 1; inserti < end; inserti++) {
let tempAnn = annMath.add(anns[inserti-1], interpolate_step); let tempAnn = annMath.add(anns[inserti - 1], interpolate_step);
if (autoAdj) if (autoAdj) {
{ try {
try
{
let adjustedAnn = await autoAdj(inserti, tempAnn); let adjustedAnn = await autoAdj(inserti, tempAnn);
let adjustedYaw = annMath.normAngle(adjustedAnn[5] - tempAnn[5]); let adjustedYaw = annMath.normAngle(adjustedAnn[5] - tempAnn[5]);
if (Math.abs(adjustedYaw) > Math.PI/2) if (Math.abs(adjustedYaw) > Math.PI / 2) {
{
console.log("adjust angle by Math.PI."); console.log("adjust angle by Math.PI.");
adjustedAnn[5] = annMath.normAngle(adjustedAnn[5] + Math.PI); adjustedAnn[5] = annMath.normAngle(adjustedAnn[5] + Math.PI);
} }
if (!pointsGlobalConfig.enableAutoRotateXY) if (!pointsGlobalConfig.enableAutoRotateXY) {
{
// adjustedAnn[3] = tempAnn[3]; // adjustedAnn[3] = tempAnn[3];
// adjustedAnn[4] = tempAnn[4]; // adjustedAnn[4] = tempAnn[4];
adjustedAnn[3] = 0; adjustedAnn[3] = 0;
adjustedAnn[4] = 0; adjustedAnn[4] = 0;
} }
tempAnn = adjustedAnn; tempAnn = adjustedAnn;
} } catch (e) {
catch (e)
{
console.log(e); console.log(e);
} }
// //
@ -368,44 +353,43 @@ var ml = {
anns[inserti] = tempAnn; anns[inserti] = tempAnn;
// adjust step since we have finished annotate one more box. // adjust step since we have finished annotate one more box.
interpolate_step = annMath.div(annMath.sub(anns[end], anns[inserti]), (end-inserti)); interpolate_step = annMath.div(
annMath.sub(anns[end], anns[inserti]),
end - inserti
);
if (onFinishOneBox) if (onFinishOneBox) onFinishOneBox(inserti);
onFinishOneBox(inserti);
} }
}else{ } else {
break; break;
} }
} }
// interpolate finished // interpolate finished
//forward //forward
i = 0; i = 0;
while (i < anns.length && !anns[i]) while (i < anns.length && !anns[i]) i++;
i++;
if (i < anns.length){ if (i < anns.length) {
let filter = new MaFilter(anns[i]); let filter = new MaFilter(anns[i]);
i++; i++;
while (i < anns.length && anns[i]){ while (i < anns.length && anns[i]) {
filter.update(anns[i]); filter.update(anns[i]);
i++; i++;
} }
while (i < anns.length && !anns[i]){ while (i < anns.length && !anns[i]) {
let tempAnn = filter.predict(); let tempAnn = filter.predict();
if (autoAdj){ if (autoAdj) {
try { try {
let adjustedAnn = await autoAdj(i, tempAnn); let adjustedAnn = await autoAdj(i, tempAnn);
let adjustedYaw = annMath.normAngle(adjustedAnn[5] - tempAnn[5]); let adjustedYaw = annMath.normAngle(adjustedAnn[5] - tempAnn[5]);
if (Math.abs(adjustedYaw) > Math.PI/2) if (Math.abs(adjustedYaw) > Math.PI / 2) {
{
console.log("adjust angle by Math.PI."); console.log("adjust angle by Math.PI.");
adjustedAnn[5] = annMath.normAngle(adjustedAnn[5] + Math.PI); adjustedAnn[5] = annMath.normAngle(adjustedAnn[5] + Math.PI);
} }
@ -417,16 +401,13 @@ var ml = {
console.log(error); console.log(error);
filter.nextStep(tempAnn); filter.nextStep(tempAnn);
} }
} else {
}
else{
filter.nextStep(tempAnn); filter.nextStep(tempAnn);
} }
anns[i] = tempAnn; anns[i] = tempAnn;
// we should update // we should update
if (onFinishOneBox) if (onFinishOneBox) onFinishOneBox(i);
onFinishOneBox(i);
i++; i++;
} }
@ -434,125 +415,115 @@ var ml = {
// now extrapolate // now extrapolate
//backward //backward
i = anns.length-1; i = anns.length - 1;
while (i >= 0 && !anns[i]) while (i >= 0 && !anns[i]) i--;
i--;
if (i >= 0){ if (i >= 0) {
let filter = new MaFilter(anns[i]); let filter = new MaFilter(anns[i]);
i--; i--;
while (i >= 0 && anns[i]){ while (i >= 0 && anns[i]) {
filter.update(anns[i]); filter.update(anns[i]);
i--; i--;
} }
while (i >= 0 && !anns[i]){ while (i >= 0 && !anns[i]) {
let tempAnn = filter.predict(); let tempAnn = filter.predict();
if (autoAdj){ if (autoAdj) {
let adjustedAnn = await autoAdj(i, tempAnn).catch(e=>{ let adjustedAnn = await autoAdj(i, tempAnn).catch((e) => {
logger.log(e); logger.log(e);
return tempAnn; return tempAnn;
}); });
let adjustedYaw = annMath.normAngle(adjustedAnn[5] - tempAnn[5]); let adjustedYaw = annMath.normAngle(adjustedAnn[5] - tempAnn[5]);
if (Math.abs(adjustedYaw) > Math.PI/2) if (Math.abs(adjustedYaw) > Math.PI / 2) {
{
console.log("adjust angle by Math.PI."); console.log("adjust angle by Math.PI.");
adjustedAnn[5] = annMath.normAngle(adjustedAnn[5] + Math.PI); adjustedAnn[5] = annMath.normAngle(adjustedAnn[5] + Math.PI);
} }
tempAnn = adjustedAnn; tempAnn = adjustedAnn;
filter.update(tempAnn); filter.update(tempAnn);
} } else {
else{
filter.nextStep(tempAnn); filter.nextStep(tempAnn);
} }
anns[i] = tempAnn; anns[i] = tempAnn;
if (onFinishOneBox) if (onFinishOneBox) onFinishOneBox(i);
onFinishOneBox(i);
i--; i--;
} }
} }
return anns; return anns;
}, },
};
function MaFilter_tf(initX) {
} // moving average filter
function MaFilter_tf(initX){ // moving average filter
this.x = tf.tensor1d(initX); // pose this.x = tf.tensor1d(initX); // pose
this.step = 0; this.step = 0;
this.v = tf.zeros([9]); // velocity this.v = tf.zeros([9]); // velocity
this.decay = tf.tensor1d([0.7, 0.7, 0.7, this.decay = tf.tensor1d([0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7]);
0.7, 0.7, 0.7,
0.7, 0.7, 0.7])
this.update = function(x){ this.update = function (x) {
if (this.step == 0){ if (this.step == 0) {
this.v = tf.sub(x, this.x); this.v = tf.sub(x, this.x);
} else { } else {
this.v = tf.add(tf.mul(tf.sub(x, this.x), this.decay), this.v = tf.add(
tf.mul(this.v, tf.sub(1, this.decay))); tf.mul(tf.sub(x, this.x), this.decay),
tf.mul(this.v, tf.sub(1, this.decay))
);
} }
this.x = x; this.x = x;
this.step++; this.step++;
}; };
this.predict = function(){ this.predict = function () {
let pred = tf.concat([tf.add(this.x, this.v).slice(0,6), this.x.slice(6)]); let pred = tf.concat([tf.add(this.x, this.v).slice(0, 6), this.x.slice(6)]);
return pred.dataSync(); return pred.dataSync();
}; };
this.nextStep = function(x){ this.nextStep = function (x) {
this.x = x; this.x = x;
this.step++; this.step++;
}; };
} }
function MaFilter(initX) {
// moving average filter
function MaFilter(initX){ // moving average filter
this.x = initX; // pose this.x = initX; // pose
this.step = 0; this.step = 0;
this.v = [0,0,0, 0,0,0, 0,0,0]; // velocity this.v = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // velocity
this.ones = [1,1,1, 1,1,1, 1,1,1]; this.ones = [1, 1, 1, 1, 1, 1, 1, 1, 1];
this.decay = [0.5, 0.5, 0.5, this.decay = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5];
0.5, 0.5, 0.5,
0.5, 0.5, 0.5];
this.update = function(x){ this.update = function (x) {
if (this.step == 0){ if (this.step == 0) {
this.v = annMath.sub(x, this.x); this.v = annMath.sub(x, this.x);
} else { } else {
this.v = annMath.add(annMath.eleMul(annMath.sub(x, this.x), this.decay), this.v = annMath.add(
annMath.eleMul(this.v, annMath.sub(this.ones, this.decay))); annMath.eleMul(annMath.sub(x, this.x), this.decay),
annMath.eleMul(this.v, annMath.sub(this.ones, this.decay))
);
} }
this.x = x; this.x = x;
this.step++; this.step++;
}; };
this.predict = function(){ this.predict = function () {
let pred = [...annMath.add(this.x, this.v).slice(0,6), ...this.x.slice(6)]; let pred = [...annMath.add(this.x, this.v).slice(0, 6), ...this.x.slice(6)];
return pred; return pred;
}; };
this.nextStep = function(x){ this.nextStep = function (x) {
this.x = x; this.x = x;
this.step++; this.step++;
}; };
} }
export {ml, MaFilter}; export { ml, MaFilter };

@ -1,177 +1,184 @@
import * as THREE from "./lib/three.module.js";
import * as THREE from './lib/three.module.js';
function Mouse(
view,
op_state,
function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_right_click, on_select_rect){ mainui_container,
this.view=view; parentUi,
on_left_click,
on_right_click,
on_select_rect
) {
this.view = view;
this.domElement = mainui_container; this.domElement = mainui_container;
this.parentUi = parentUi; this.parentUi = parentUi;
this.operation_state = op_state; this.operation_state = op_state;
this.domElement.addEventListener(
this.domElement.addEventListener( 'mousemove', (e)=>{this.onMouseMove(e);}, false ); "mousemove",
this.domElement.addEventListener( 'mousedown', (e)=>{this.onMouseDown(e);}, true ); (e) => {
this.onMouseMove(e);
},
false
);
this.domElement.addEventListener(
"mousedown",
(e) => {
this.onMouseDown(e);
},
true
);
this.raycaster = new THREE.Raycaster(); this.raycaster = new THREE.Raycaster();
this.onDownPosition = new THREE.Vector2(); this.onDownPosition = new THREE.Vector2();
this.onUpPosition = new THREE.Vector2(); this.onUpPosition = new THREE.Vector2();
this.handleLeftClick = on_left_click; this.handleLeftClick = on_left_click;
this.handleRightClick = on_right_click; this.handleRightClick = on_right_click;
this.handleSelectRect = on_select_rect; this.handleSelectRect = on_select_rect;
var in_select_mode = false; var in_select_mode = false;
var select_start_pos; var select_start_pos;
var select_end_pos; var select_end_pos;
this.get_mouse_location_in_world = function(){ this.get_mouse_location_in_world = function () {
this.raycaster.setFromCamera( this.onUpPosition, this.view.camera ); this.raycaster.setFromCamera(this.onUpPosition, this.view.camera);
var o = this.raycaster.ray.origin; var o = this.raycaster.ray.origin;
var d = this.raycaster.ray.direction; var d = this.raycaster.ray.direction;
var alpha = - o.z/d.z; var alpha = -o.z / d.z;
var x = o.x + d.x*alpha; var x = o.x + d.x * alpha;
var y = o.y + d.y*alpha; var y = o.y + d.y * alpha;
return {x:x, y:y, z:0}; return { x: x, y: y, z: 0 };
}; };
this.get_screen_location_in_world = function (x, y) {
this.get_screen_location_in_world = function(x,y){
var screen_pos = new THREE.Vector2(); var screen_pos = new THREE.Vector2();
screen_pos.x = x; screen_pos.x = x;
screen_pos.y = y; screen_pos.y = y;
this.raycaster.setFromCamera( screen_pos, this.view.camera ); this.raycaster.setFromCamera(screen_pos, this.view.camera);
var o = this.raycaster.ray.origin; var o = this.raycaster.ray.origin;
var d = this.raycaster.ray.direction; var d = this.raycaster.ray.direction;
var alpha = - o.z/d.z; var alpha = -o.z / d.z;
var x = o.x + d.x*alpha; var x = o.x + d.x * alpha;
var y = o.y + d.y*alpha; var y = o.y + d.y * alpha;
return {x:x, y:y, z:0}; return { x: x, y: y, z: 0 };
}; };
this.getMousePosition = function (dom, offsetX, offsetY) {
return [
(offsetX / dom.clientWidth) * 2 - 1,
this.getMousePosition = function( dom, offsetX, offsetY ) { (-offsetY / dom.clientHeight) * 2 + 1,
];
return [offsetX/dom.clientWidth * 2 - 1, - offsetY/dom.clientHeight * 2 + 1];
}; };
this.getIntersects = function( point, objects ) { this.getIntersects = function (point, objects) {
// mouse is temp var // mouse is temp var
let mouse = new THREE.Vector2(); let mouse = new THREE.Vector2();
mouse.set(point.x, point.y); mouse.set(point.x, point.y);
this.raycaster.setFromCamera( mouse, this.view.camera ); this.raycaster.setFromCamera(mouse, this.view.camera);
return this.raycaster.intersectObjects( objects, false ); // 2nd argument: recursive.
return this.raycaster.intersectObjects(objects, false); // 2nd argument: recursive.
}; };
this.onMouseDown = function (event) {
this.onMouseDown=function( event ) {
in_select_mode = false; in_select_mode = false;
if (event.which==3){ if (event.which == 3) {
this.operation_state.key_pressed = false; this.operation_state.key_pressed = false;
} else if (event.which == 1){ } else if (event.which == 1) {
console.log("mouse left key down!"); console.log("mouse left key down!");
if (event.ctrlKey || event.shiftKey){ if (event.ctrlKey || event.shiftKey) {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
in_select_mode = true; in_select_mode = true;
select_start_pos={ select_start_pos = {
x: event.offsetX, x: event.offsetX,
y: event.offsetY, y: event.offsetY,
} };
} }
} }
var array = this.getMousePosition(this.domElement, event.offsetX, event.offsetY ); var array = this.getMousePosition(
this.onDownPosition.fromArray( array ); this.domElement,
event.offsetX,
event.offsetY
);
this.onDownPosition.fromArray(array);
console.log("mouse down", array); console.log("mouse down", array);
this.domElement.addEventListener( 'mouseup', on_mouse_up, false ); this.domElement.addEventListener("mouseup", on_mouse_up, false);
};
}
this.onMouseMove=function( event ) { this.onMouseMove = function (event) {
event.preventDefault(); event.preventDefault();
//console.log(this.getMousePosition(this.domElement, event.offsetX, event.offsetY)); //console.log(this.getMousePosition(this.domElement, event.offsetX, event.offsetY));
if (in_select_mode){ if (in_select_mode) {
select_end_pos = {
select_end_pos={
x: event.offsetX, x: event.offsetX,
y: event.offsetY, y: event.offsetY,
}; };
if (
if (event.offsetX != select_start_pos.x || event.offsetY != select_end_pos.y){ event.offsetX != select_start_pos.x ||
event.offsetY != select_end_pos.y
) {
//draw select box //draw select box
var sbox = this.parentUi.querySelector("#select-box"); var sbox = this.parentUi.querySelector("#select-box");
sbox.style.display="inherit"; sbox.style.display = "inherit";
if (select_start_pos.x < select_end_pos.x){ if (select_start_pos.x < select_end_pos.x) {
sbox.style.left = select_start_pos.x + 'px'; sbox.style.left = select_start_pos.x + "px";
sbox.style.width = select_end_pos.x - select_start_pos.x + 'px'; sbox.style.width = select_end_pos.x - select_start_pos.x + "px";
}else { } else {
sbox.style.left = select_end_pos.x + 'px'; sbox.style.left = select_end_pos.x + "px";
sbox.style.width = -select_end_pos.x + select_start_pos.x + 'px'; sbox.style.width = -select_end_pos.x + select_start_pos.x + "px";
} }
if (select_start_pos.y < select_end_pos.y){ if (select_start_pos.y < select_end_pos.y) {
sbox.style.top = select_start_pos.y + 'px'; sbox.style.top = select_start_pos.y + "px";
sbox.style.height = select_end_pos.y - select_start_pos.y + 'px'; sbox.style.height = select_end_pos.y - select_start_pos.y + "px";
}else { } else {
sbox.style.top = select_end_pos.y + 'px'; sbox.style.top = select_end_pos.y + "px";
sbox.style.height = -select_end_pos.y + select_start_pos.y + 'px'; sbox.style.height = -select_end_pos.y + select_start_pos.y + "px";
} }
} }
} }
};
} var on_mouse_up = (e) => {
this.onMouseUp(e);
var on_mouse_up = (e)=>{this.onMouseUp(e)}; };
this.onMouseUp=function( event ) {
this.domElement.removeEventListener( 'mouseup', on_mouse_up, false );
this.onMouseUp = function (event) {
this.domElement.removeEventListener("mouseup", on_mouse_up, false);
var array = this.getMousePosition(this.domElement, event.offsetX, event.offsetY ); var array = this.getMousePosition(
this.onUpPosition.fromArray( array ); this.domElement,
event.offsetX,
event.offsetY
);
this.onUpPosition.fromArray(array);
console.log("mouse up", array); console.log("mouse up", array);
if ( this.onDownPosition.distanceTo( this.onUpPosition ) === 0 ) { if (this.onDownPosition.distanceTo(this.onUpPosition) === 0) {
if (event.which == 3){ if (event.which == 3) {
//right click //right click
// if no other key pressed, we consider this as a right click // if no other key pressed, we consider this as a right click
if (!this.operation_state.key_pressed){ if (!this.operation_state.key_pressed) {
console.log("right clicked."); console.log("right clicked.");
this.handleRightClick(event); this.handleRightClick(event);
} }
} } else {
else{
// left click // left click
this.handleLeftClick(event); this.handleLeftClick(event);
} }
@ -180,42 +187,36 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
return; return;
} }
if (in_select_mode) {
if (in_select_mode){
in_select_mode = false; in_select_mode = false;
var sbox = this.parentUi.querySelector("#select-box"); var sbox = this.parentUi.querySelector("#select-box");
sbox.style.display="none"; sbox.style.display = "none";
if (this.handleSelectRect){ if (this.handleSelectRect) {
var x,y,w,h; var x, y, w, h;
if (this.onDownPosition.x < this.onUpPosition.x){ if (this.onDownPosition.x < this.onUpPosition.x) {
x = this.onDownPosition.x; x = this.onDownPosition.x;
w = this.onUpPosition.x - this.onDownPosition.x; w = this.onUpPosition.x - this.onDownPosition.x;
} } else {
else{
x = this.onUpPosition.x; x = this.onUpPosition.x;
w = this.onDownPosition.x - this.onUpPosition.x; w = this.onDownPosition.x - this.onUpPosition.x;
} }
if (this.onDownPosition.y < this.onUpPosition.y){ if (this.onDownPosition.y < this.onUpPosition.y) {
y = this.onDownPosition.y; y = this.onDownPosition.y;
h = this.onUpPosition.y - this.onDownPosition.y; h = this.onUpPosition.y - this.onDownPosition.y;
} } else {
else{
y = this.onUpPosition.y; y = this.onUpPosition.y;
h = this.onDownPosition.y - this.onUpPosition.y; h = this.onDownPosition.y - this.onUpPosition.y;
} }
console.log("select rect",x,y,w,h); console.log("select rect", x, y, w, h);
this.handleSelectRect(x,y,w,h, event.ctrlKey, event.shiftKey); this.handleSelectRect(x, y, w, h, event.ctrlKey, event.shiftKey);
}
} }
} }
};
} }
export{Mouse} export { Mouse };

@ -1,99 +1,120 @@
// size is the dimension of the object in x/y/z axis, with unit meter. // size is the dimension of the object in x/y/z axis, with unit meter.
class ObjectCategory class ObjectCategory {
{
obj_type_map = { obj_type_map = {
Car: {color: '#86af49', size:[4.5, 1.8, 1.5], attr:["door open", "trunk open"]}, Car: {
Pedestrian: {color: '#ff0000', size:[0.4, 0.5, 1.7], attr:["umbrella", "sitting", "squating", "bending over", "luggage"]}, color: "#86af49",
Van: {color: '#00ff00', size:[4.5, 1.8, 1.5], attr:["door open", "trunk open"]}, size: [4.5, 1.8, 1.5],
Bus: {color: '#ffff00', size:[13, 3, 3.5]}, attr: ["door open", "trunk open"],
Truck: {color: '#00ffff', size:[10., 2.8, 3]}, },
Pedestrian: {
ScooterRider: {color: '#ff8800', size:[1.6, 0.6, 1.6], attr:["umbrella", "1 passenger", "2 passengers", "3 passengers"]}, color: "#ff0000",
Scooter: {color: '#aaaa00', size:[1.6, 0.6, 1.0]}, size: [0.4, 0.5, 1.7],
attr: ["umbrella", "sitting", "squating", "bending over", "luggage"],
},
BicycleRider: {color: '#88ff00', size:[1.6, 0.6, 1.7], attr:["umbrella", "1 passenger", "2 passengers", "3 passengers"]}, Van: {
Bicycle: {color: '#ff8800', size:[1.6, 0.6, 1.2], attr:["laying down"]}, color: "#00ff00",
size: [4.5, 1.8, 1.5],
attr: ["door open", "trunk open"],
Motorcycle: {color: '#aaaa00', size:[1.6, 0.6, 1.2], attr:["umbrella"]}, },
MotorcyleRider: {color: '#ff8800', size:[1.6, 0.6, 1.6], attr:["umbrella", "1 passenger", "2 passengers", "3 passengers"]}, Bus: { color: "#ffff00", size: [13, 3, 3.5] },
Truck: { color: "#00ffff", size: [10, 2.8, 3] },
ScooterRider: {
PoliceCar: {color: '#86af49', size:[4.5, 1.8, 1.5]}, color: "#ff8800",
TourCar: {color: '#86af49', size:[4.4, 1.5, 2.2]}, size: [1.6, 0.6, 1.6],
attr: ["umbrella", "1 passenger", "2 passengers", "3 passengers"],
RoadWorker: {color: '#ff0000', size:[0.4, 0.5, 1.7]}, },
Child: {color: '#ff0000', size:[0.4, 0.5, 1.2]}, Scooter: { color: "#aaaa00", size: [1.6, 0.6, 1.0] },
BicycleRider: {
color: "#88ff00",
size: [1.6, 0.6, 1.7],
attr: ["umbrella", "1 passenger", "2 passengers", "3 passengers"],
},
Bicycle: { color: "#ff8800", size: [1.6, 0.6, 1.2], attr: ["laying down"] },
Motorcycle: { color: "#aaaa00", size: [1.6, 0.6, 1.2], attr: ["umbrella"] },
MotorcyleRider: {
color: "#ff8800",
size: [1.6, 0.6, 1.6],
attr: ["umbrella", "1 passenger", "2 passengers", "3 passengers"],
},
PoliceCar: { color: "#86af49", size: [4.5, 1.8, 1.5] },
TourCar: { color: "#86af49", size: [4.4, 1.5, 2.2] },
RoadWorker: { color: "#ff0000", size: [0.4, 0.5, 1.7] },
Child: { color: "#ff0000", size: [0.4, 0.5, 1.2] },
//Crowd: {color: '#ff0000', size:[1.6, 0.6, 1.2]}, //Crowd: {color: '#ff0000', size:[1.6, 0.6, 1.2]},
BabyCart: {color: '#ff0000', size:[0.8, 0.5, 1.0]}, BabyCart: { color: "#ff0000", size: [0.8, 0.5, 1.0] },
Cart: {color: '#ff0000', size:[0.8, 0.5, 1.0]}, Cart: { color: "#ff0000", size: [0.8, 0.5, 1.0] },
Cone: {color: '#ff0000', size:[0.3, 0.3, 0.6]}, Cone: { color: "#ff0000", size: [0.3, 0.3, 0.6] },
FireHydrant: {color: '#ff0000', size:[0.4, 0.4, 0.6]}, FireHydrant: { color: "#ff0000", size: [0.4, 0.4, 0.6] },
SaftyTriangle: {color: '#ff0000', size:[0.3, 0.4, 0.4]}, SaftyTriangle: { color: "#ff0000", size: [0.3, 0.4, 0.4] },
PlatformCart: {color: '#ff0000', size:[1.2, 0.8, 1.0]}, PlatformCart: { color: "#ff0000", size: [1.2, 0.8, 1.0] },
ConstructionCart: {color: '#ff0000', size:[1.2, 0.8, 1.0]}, ConstructionCart: { color: "#ff0000", size: [1.2, 0.8, 1.0] },
RoadBarrel: {color: '#ff0000', size:[0.5, 0.5, 0.6]}, RoadBarrel: { color: "#ff0000", size: [0.5, 0.5, 0.6] },
TrafficBarrier: {color: '#ff0000', size:[1.5, 0.3, 1.2]}, TrafficBarrier: { color: "#ff0000", size: [1.5, 0.3, 1.2] },
LongVehicle: {color: '#ff0000', size:[16, 3, 3]}, LongVehicle: { color: "#ff0000", size: [16, 3, 3] },
BicycleGroup: { color: "#ff0000", size: [1.6, 0.6, 1.2] },
BicycleGroup: {color: '#ff0000', size:[1.6, 0.6, 1.2]},
ConcreteTruck: { color: "#00ffff", size: [10, 2.8, 3] },
Tram: { color: "#00ffff", size: [10, 2.8, 3] },
ConcreteTruck: {color: '#00ffff', size:[10., 2.8, 3]}, Excavator: { color: "#00ffff", size: [6, 3, 3] },
Tram: {color: '#00ffff', size:[10., 2.8, 3]},
Excavator: {color: '#00ffff', size:[6., 3, 3]}, Animal: { color: "#00aaff", size: [1.6, 0.6, 1.2] },
Animal: {color: '#00aaff', size:[1.6, 0.6, 1.2]}, TrashCan: { color: "#00aaff", size: [0.6, 0.4, 1.0] },
TrashCan: {color: '#00aaff', size:[0.6, 0.4, 1.0]}, ForkLift: { color: "#00aaff", size: [5.0, 1.2, 2.0] },
Trimotorcycle: { color: "#00aaff", size: [2.6, 1.0, 1.6] },
ForkLift: {color: '#00aaff', size:[5.0, 1.2, 2.0]}, FreightTricycle: { color: "#00aaff", size: [2.6, 1.0, 1.6] },
Trimotorcycle: {color: '#00aaff', size:[2.6, 1.0, 1.6]}, Crane: { color: "#00aaff", size: [5.0, 1.2, 2.0] },
FreightTricycle: {color: '#00aaff', size:[2.6, 1.0, 1.6]}, RoadRoller: { color: "#00aaff", size: [2.7, 1.5, 2.0] },
Crane: {color: '#00aaff', size:[5.0, 1.2, 2.0]}, Bulldozer: { color: "#00aaff", size: [3.0, 2.0, 2.0] },
RoadRoller: {color: '#00aaff', size:[2.7, 1.5, 2.0]},
Bulldozer: {color: '#00aaff', size:[3.0, 2.0, 2.0]}, DontCare: { color: "#00ff88", size: [4, 4, 3] },
Misc: { color: "#008888", size: [4.5, 1.8, 1.5] },
DontCare: {color: '#00ff88', size:[4, 4, 3]}, Unknown: { color: "#008888", size: [4.5, 1.8, 1.5] },
Misc: {color: '#008888', size:[4.5, 1.8, 1.5]}, Unknown1: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown: {color: '#008888', size:[4.5, 1.8, 1.5]}, Unknown2: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown1: {color: '#008888', size:[4.5, 1.8, 1.5]}, Unknown3: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown2: {color: '#008888', size:[4.5, 1.8, 1.5]}, Unknown4: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown3: {color: '#008888', size:[4.5, 1.8, 1.5]}, Unknown5: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown4: {color: '#008888', size:[4.5, 1.8, 1.5]},
Unknown5: {color: '#008888', size:[4.5, 1.8, 1.5]},
}; };
constructor() {}
constructor(){
popularCategories = [
} "Car",
"Pedestrian",
popularCategories = ["Car", "Pedestrian", "Van", "Bus", "Truck", "Scooter", "ScooterRider", "Bicycle", "BicycleRider"]; "Van",
"Bus",
guess_obj_type_by_dimension(scale){ "Truck",
"Scooter",
"ScooterRider",
"Bicycle",
"BicycleRider",
];
guess_obj_type_by_dimension(scale) {
var max_score = 0; var max_score = 0;
var max_name = 0; var max_name = 0;
this.popularCategories.forEach(i=>{ this.popularCategories.forEach((i) => {
var o = this.obj_type_map[i]; var o = this.obj_type_map[i];
var scorex = o.size[0]/scale.x; var scorex = o.size[0] / scale.x;
var scorey = o.size[1]/scale.y; var scorey = o.size[1] / scale.y;
var scorez = o.size[2]/scale.z; var scorez = o.size[2] / scale.z;
if (scorex>1) scorex = 1/scorex; if (scorex > 1) scorex = 1 / scorex;
if (scorey>1) scorey = 1/scorey; if (scorey > 1) scorey = 1 / scorey;
if (scorez>1) scorez = 1/scorez; if (scorez > 1) scorez = 1 / scorez;
if (scorex + scorey + scorez > max_score){ if (scorex + scorey + scorez > max_score) {
max_score = scorex + scorey + scorez; max_score = scorex + scorey + scorez;
max_name = i; max_name = i;
} }
@ -104,40 +125,40 @@ class ObjectCategory
} }
global_color_idx = 0; global_color_idx = 0;
get_color_by_id(id){ get_color_by_id(id) {
let idx = parseInt(id); let idx = parseInt(id);
if (!idx) if (!idx) {
{
idx = this.global_color_idx; idx = this.global_color_idx;
this.global_color_idx += 1; this.global_color_idx += 1;
} }
idx %= 33; idx %= 33;
idx = idx*19 % 33; idx = (idx * 19) % 33;
return { return {
x: idx*8/256.0, x: (idx * 8) / 256.0,
y: 1- idx*8/256.0, y: 1 - (idx * 8) / 256.0,
z: (idx<16)?(idx*2*8/256.0):((32-idx)*2*8/256.0), z: idx < 16 ? (idx * 2 * 8) / 256.0 : ((32 - idx) * 2 * 8) / 256.0,
}; };
} }
get_color_by_category(category){ get_color_by_category(category) {
let target_color_hex = parseInt("0x"+this.get_obj_cfg_by_type(category).color.slice(1)); let target_color_hex = parseInt(
"0x" + this.get_obj_cfg_by_type(category).color.slice(1)
);
return { return {
x: (target_color_hex/256/256)/255.0, x: target_color_hex / 256 / 256 / 255.0,
y: (target_color_hex/256 % 256)/255.0, y: ((target_color_hex / 256) % 256) / 255.0,
z: (target_color_hex % 256)/255.0, z: (target_color_hex % 256) / 255.0,
}; };
} }
get_obj_cfg_by_type(name){ get_obj_cfg_by_type(name) {
if (this.obj_type_map[name]){ if (this.obj_type_map[name]) {
return this.obj_type_map[name]; return this.obj_type_map[name];
} } else {
else{
return this.obj_type_map["Unknown"]; return this.obj_type_map["Unknown"];
} }
} }
@ -150,7 +171,6 @@ class ObjectCategory
// } // }
// } // }
// get_next_obj_type_name(name){ // get_next_obj_type_name(name){
// if (name_array.length == 0) { // if (name_array.length == 0) {
@ -163,10 +183,8 @@ class ObjectCategory
// return name_array[idx]; // return name_array[idx];
// } // }
} }
let globalObjectCategory = new ObjectCategory(); let globalObjectCategory = new ObjectCategory();
export {globalObjectCategory}; export { globalObjectCategory };

@ -1,45 +1,52 @@
class ObjectIdManager {
class ObjectIdManager
{
maxId = 1; maxId = 1;
objectList = []; objectList = [];
//todo: should use all worldlist //todo: should use all worldlist
generateNewUniqueId(world){ generateNewUniqueId(world) {
this.maxId += 1; this.maxId += 1;
return this.maxId; return this.maxId;
} }
scene = ""; scene = "";
setCurrentScene(scene, done) setCurrentScene(scene, done) {
{ if (scene != this.scene) {
if (scene != this.scene)
{
this.scene = scene; this.scene = scene;
this.load_obj_ids_of_scene(scene, done); this.load_obj_ids_of_scene(scene, done);
} }
} }
forceUpdate(done) forceUpdate(done) {
{
this.load_obj_ids_of_scene(this.scene, done); this.load_obj_ids_of_scene(this.scene, done);
} }
// should just tell editor // should just tell editor
// don't change html elements directly. // don't change html elements directly.
setObjdIdListOptions() setObjdIdListOptions() {
{ let objSelOptions = this.objectList
let objSelOptions = this.objectList.map(function(c){ .map(function (c) {
return "<option value="+c.id+">"+String(c.id) +"-"+ c.category+"</option>"; return (
}).reduce(function(x,y){return x+y;}, "<option value=" +
"<option>--object--</option>"); c.id +
">" +
String(c.id) +
"-" +
c.category +
"</option>"
);
})
.reduce(function (x, y) {
return x + y;
}, "<option>--object--</option>");
document.getElementById("object-selector").innerHTML = objSelOptions; document.getElementById("object-selector").innerHTML = objSelOptions;
let objIdsOptions = this.objectList
let objIdsOptions = this.objectList.map(function(c){ .map(function (c) {
return "<option value="+c.id+">"+c.category+"</option>"; return "<option value=" + c.id + ">" + c.category + "</option>";
}).reduce(function(x,y){return x+y;}, })
.reduce(
function (x, y) {
return x + y;
},
//"<option value='auto'></option><option value='new'></option>"); //"<option value='auto'></option><option value='new'></option>");
//"<option value='new'>suggest a new id</option>" //"<option value='new'>suggest a new id</option>"
"" ""
@ -48,70 +55,65 @@ class ObjectIdManager
document.getElementById("obj-ids-of-scene").innerHTML = objIdsOptions; document.getElementById("obj-ids-of-scene").innerHTML = objIdsOptions;
} }
sortObjIdList() sortObjIdList() {
{ this.objectList = this.objectList.sort(function (x, y) {
this.objectList = this.objectList.sort(function(x, y){
return parseInt(x.id) - parseInt(y.id); return parseInt(x.id) - parseInt(y.id);
}); });
} }
// called when 1) new object 2) category/id modified // called when 1) new object 2) category/id modified
addObject(obj) addObject(obj) {
{ if (
if (! this.objectList.find(x=>x.id == obj.id && x.category == obj.category)) !this.objectList.find((x) => x.id == obj.id && x.category == obj.category)
{ ) {
this.objectList.push(obj); this.objectList.push(obj);
this.sortObjIdList(); this.sortObjIdList();
this.setObjdIdListOptions(); this.setObjdIdListOptions();
if (obj.id > this.maxId) if (obj.id > this.maxId) {
{
this.maxId = parseInt(obj.id); this.maxId = parseInt(obj.id);
} }
} }
} }
load_obj_ids_of_scene(scene, done){ load_obj_ids_of_scene(scene, done) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
// we defined the xhr // we defined the xhr
let self =this; let self = this;
xhr.onreadystatechange = function() { xhr.onreadystatechange = function () {
if (this.readyState != 4) if (this.readyState != 4) return;
return;
if (this.status == 200) { if (this.status == 200) {
var ret = JSON.parse(this.responseText); var ret = JSON.parse(this.responseText);
self.objectList = ret; self.objectList = ret;
self.sortObjIdList(); self.sortObjIdList();
self.maxId = Math.max(...ret.map(function(x){return x.id;})); self.maxId = Math.max(
if (self.maxId < 0) // this is -infinity if there is no ids. ...ret.map(function (x) {
return x.id;
})
);
if (self.maxId < 0)
// this is -infinity if there is no ids.
self.maxId = 0; self.maxId = 0;
self.setObjdIdListOptions(); self.setObjdIdListOptions();
if (done) if (done) done(ret);
done(ret)
} }
}; };
xhr.open('GET', "/objs_of_scene?scene="+scene, true); xhr.open("GET", "/objs_of_scene?scene=" + scene, true);
xhr.send(); xhr.send();
} }
getObjById(id) {
getObjById(id) return this.objectList.find((x) => x.id == id);
{
return this.objectList.find(x=>x.id == id);
} }
} }
let objIdManager = new ObjectIdManager(); let objIdManager = new ObjectIdManager();
export { objIdManager };
export {objIdManager};

@ -1,85 +1,76 @@
import * as THREE from './lib/three.module.js'; import * as THREE from "./lib/three.module.js";
import { PCDLoader } from './lib/PCDLoader.js'; import { PCDLoader } from "./lib/PCDLoader.js";
import { OrbitControls } from './lib/OrbitControls.js'; import { OrbitControls } from "./lib/OrbitControls.js";
import { SelectionBox } from './lib/SelectionBox.js'; import { SelectionBox } from "./lib/SelectionBox.js";
import { SelectionHelper } from './lib/SelectionHelper.js'; import { SelectionHelper } from "./lib/SelectionHelper.js";
var container; var container;
var camera, controls, scene, renderer; var camera, controls, scene, renderer;
var camera; var camera;
var url_string = window.location.href;
var url_string = window.location.href
var url = new URL(url_string); var url = new URL(url_string);
//language //language
var pcd_file = url.searchParams.get("file"); var pcd_file = url.searchParams.get("file");
init(); init();
animate(); animate();
function init() { function init() {
document.body.addEventListener('keydown', event => { document.body.addEventListener("keydown", (event) => {
if (event.ctrlKey && 'asdv'.indexOf(event.key) !== -1) { if (event.ctrlKey && "asdv".indexOf(event.key) !== -1) {
event.preventDefault() event.preventDefault();
} }
}) });
scene = new THREE.Scene(); scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
camera = new THREE.PerspectiveCamera(
renderer = new THREE.WebGLRenderer( { antialias: true } ); 65,
renderer.setPixelRatio( window.devicePixelRatio ); window.innerWidth / window.innerHeight,
1,
800
);
camera = new THREE.PerspectiveCamera( 65, window.innerWidth / window.innerHeight, 1, 800 );
camera.position.x = 0; camera.position.x = 0;
camera.position.z = 50; camera.position.z = 50;
camera.position.y = 0; camera.position.y = 0;
camera.up.set( 0, 0, 1); camera.up.set(0, 0, 1);
camera.lookAt( 0, 0, 0 ); camera.lookAt(0, 0, 0);
controls = new OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)
container = document.createElement( 'container' ); controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", render); // call this only in static scenes (i.e., if there is no animation loop)
container = document.createElement("container");
document.body.appendChild( container ); document.body.appendChild(container);
container.appendChild( renderer.domElement ); container.appendChild(renderer.domElement);
document.addEventListener("keydown", keydown) document.addEventListener("keydown", keydown);
scene.add( new THREE.AxesHelper( 2 ) ); scene.add(new THREE.AxesHelper(2));
onWindowResize(); onWindowResize();
window.addEventListener( 'resize', onWindowResize, false ); window.addEventListener("resize", onWindowResize, false);
load_all(); load_all();
render(); render();
} }
function load_all(){ function load_all() {
load_pcd("pcd", pcd_file, 0xff0000); load_pcd("pcd", pcd_file, 0xff0000);
} }
function keydown(ev) {
function keydown( ev ) { switch (ev.key) {
case "+":
switch ( ev.key) {
case '+':
clouds["src"].material.size *= 1.2; clouds["src"].material.size *= 1.2;
clouds["tgt"].material.size *= 1.2; clouds["tgt"].material.size *= 1.2;
clouds["out"].material.size *= 1.2; clouds["out"].material.size *= 1.2;
break; break;
case '-': case "-":
clouds["src"].material.size /= 1.2; clouds["src"].material.size /= 1.2;
clouds["tgt"].material.size /= 1.2; clouds["tgt"].material.size /= 1.2;
clouds["out"].material.size /= 1.2; clouds["out"].material.size /= 1.2;
@ -88,105 +79,110 @@ function keydown( ev ) {
} }
} }
function onWindowResize() { function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight; camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setSize(window.innerWidth, window.innerHeight);
} }
function animate() { function animate() {
requestAnimationFrame( animate ); requestAnimationFrame(animate);
controls.update(); controls.update();
render(); render();
} }
function render() {
function render(){ renderer.render(scene, camera);
renderer.render( scene, camera );
} }
function load_pcd(name, file, overall_color) {
function load_pcd(name, file, overall_color){
var loader = new PCDLoader(); var loader = new PCDLoader();
loader.load( file, loader.load(file, function (pcd) {
function ( pcd ) {
var position = pcd.position; var position = pcd.position;
var color = pcd.color; var color = pcd.color;
var normal = pcd.normal; var normal = pcd.normal;
// build geometry // build geometry
var geometry = new THREE.BufferGeometry(); var geometry = new THREE.BufferGeometry();
if ( position.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); if (position.length > 0)
if ( normal.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal, 3 ) ); geometry.addAttribute(
if ( color.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) ); "position",
new THREE.Float32BufferAttribute(position, 3)
);
if (normal.length > 0)
geometry.addAttribute(
"normal",
new THREE.Float32BufferAttribute(normal, 3)
);
if (color.length > 0)
geometry.addAttribute(
"color",
new THREE.Float32BufferAttribute(color, 3)
);
geometry.computeBoundingSphere(); geometry.computeBoundingSphere();
// build material // build material
var material = new THREE.PointsMaterial( { size: 0.005 } ); var material = new THREE.PointsMaterial({ size: 0.005 });
if ( color.length > 0 ) { if (color.length > 0) {
material.vertexColors = VertexColors; material.vertexColors = VertexColors;
} else { } else {
material.color.setHex(overall_color ); material.color.setHex(overall_color);
} }
//material.size = 0.1; //material.size = 0.1;
// build mesh // build mesh
var mesh = new THREE.Points( geometry, material ); var mesh = new THREE.Points(geometry, material);
mesh.name = "pcd"; mesh.name = "pcd";
//return mesh; //return mesh;
scene.add(mesh); scene.add(mesh);
//var center = points.geometry.boundingSphere.center; //var center = points.geometry.boundingSphere.center;
//controls.target.set( center.x, center.y, center.z ); //controls.target.set( center.x, center.y, center.z );
//controls.update(); //controls.update();
}, });
);
} }
var selectionBox = new SelectionBox(camera, scene);
var helper = new SelectionHelper(selectionBox, renderer, "selectBox");
var selectionBox = new SelectionBox( camera, scene ); document.addEventListener("mousedown", function (event) {
var helper = new SelectionHelper( selectionBox, renderer, 'selectBox' ); for (var item of selectionBox.collection) {
document.addEventListener( 'mousedown', function ( event ) { item.material.emissive.set(0x000000);
for ( var item of selectionBox.collection ) {
item.material.emissive.set( 0x000000 );
} }
selectionBox.startPoint.set( selectionBox.startPoint.set(
( event.clientX / window.innerWidth ) * 2 - 1, (event.clientX / window.innerWidth) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1, -(event.clientY / window.innerHeight) * 2 + 1,
0.5 ); 0.5
} ); );
document.addEventListener( 'mousemove', function ( event ) { });
if ( helper.isDown ) { document.addEventListener("mousemove", function (event) {
for ( var i = 0; i < selectionBox.collection.length; i ++ ) { if (helper.isDown) {
selectionBox.collection[ i ].material.emissive.set( 0x000000 ); for (var i = 0; i < selectionBox.collection.length; i++) {
selectionBox.collection[i].material.emissive.set(0x000000);
} }
selectionBox.endPoint.set( selectionBox.endPoint.set(
( event.clientX / window.innerWidth ) * 2 - 1, (event.clientX / window.innerWidth) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1, -(event.clientY / window.innerHeight) * 2 + 1,
0.5 ); 0.5
);
var allSelected = selectionBox.select(); var allSelected = selectionBox.select();
for ( var i = 0; i < allSelected.length; i ++ ) { for (var i = 0; i < allSelected.length; i++) {
allSelected[ i ].material.emissive.set( 0xffffff ); allSelected[i].material.emissive.set(0xffffff);
} }
} }
} ); });
document.addEventListener( 'mouseup', function ( event ) { document.addEventListener("mouseup", function (event) {
selectionBox.endPoint.set( selectionBox.endPoint.set(
( event.clientX / window.innerWidth ) * 2 - 1, (event.clientX / window.innerWidth) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1, -(event.clientY / window.innerHeight) * 2 + 1,
0.5 ); 0.5
);
var allSelected = selectionBox.select(); var allSelected = selectionBox.select();
for ( var i = 0; i < allSelected.length; i ++ ) { for (var i = 0; i < allSelected.length; i++) {
allSelected[ i ].material.emissive.set( 0xffffff ); allSelected[i].material.emissive.set(0xffffff);
} }
} ); });

@ -1,31 +1,26 @@
function PlayControl(data) {
function PlayControl(data){
this.data = data; this.data = data;
this.stop_play_flag=true; this.stop_play_flag = true;
this.pause_play_flag=false; this.pause_play_flag = false;
this.pause_resume_play=function(){ this.pause_resume_play = function () {
this.pause_play_flag=!this.pause_play_flag; this.pause_play_flag = !this.pause_play_flag;
if (!this.pause_play_flag && !this.stop_play_flag){ if (!this.pause_play_flag && !this.stop_play_flag) {
this.play(this.on_load_world_finished); this.play(this.on_load_world_finished);
} }
}; };
this.stop_play = function () {
this.stop_play=function(){ this.stop_play_flag = true;
this.stop_play_flag=true; this.pause_play_flag = false;
this.pause_play_flag=false;
}; };
this.on_load_world_finished = null; this.on_load_world_finished = null;
this.play=function(on_load_world_finished, fps=2){ this.play = function (on_load_world_finished, fps = 2) {
this.on_load_world_finished = on_load_world_finished; this.on_load_world_finished = on_load_world_finished;
if (!this.data.meta){ if (!this.data.meta) {
console.log("no meta data! cannot play"); console.log("no meta data! cannot play");
return; return;
} }
@ -39,117 +34,95 @@ function PlayControl(data){
var scene_meta = data.world.sceneMeta; var scene_meta = data.world.sceneMeta;
var scope=this; var scope = this;
let start_frame = data.world.frameInfo.frame; let start_frame = data.world.frameInfo.frame;
let current_frame_index = scene_meta.frames.findIndex(function(x){return x == data.world.frameInfo.frame;}) let current_frame_index = scene_meta.frames.findIndex(function (x) {
if (current_frame_index == scene_meta.frames.length-1) return x == data.world.frameInfo.frame;
{ });
if (current_frame_index == scene_meta.frames.length - 1) {
//this is the last frmae //this is the last frmae
// we go to first frame. // we go to first frame.
start_frame = scene_meta.frames[0]; start_frame = scene_meta.frames[0];
} }
play_frame(scene_meta, start_frame, on_load_world_finished); play_frame(scene_meta, start_frame, on_load_world_finished);
async function play_frame(scene_meta, frame, on_load_world_finished) {
if (!scope.stop_play_flag && !scope.pause_play_flag) {
var world = await scope.data.getWorld(scene_meta.scene, frame);
async function play_frame(scene_meta, frame, on_load_world_finished){ if (world.preloaded()) {
if (!scope.stop_play_flag && !scope.pause_play_flag) //found, data ready
{ scope.data.activate_world(world, function () {
var world = await scope.data.getWorld(scene_meta.scene, frame) //on load finished
if (world.preloaded()) //found, data ready
{
scope.data.activate_world(
world,
function(){//on load finished
//views[0].detach_control(); //views[0].detach_control();
on_load_world_finished(world); on_load_world_finished(world);
// play next frame // play next frame
let frame_index = world.frameInfo.frame_index; let frame_index = world.frameInfo.frame_index;
if (frame_index+1 < scene_meta.frames.length) if (frame_index + 1 < scene_meta.frames.length) {
{ var next_frame = scene_meta.frames[frame_index + 1];
var next_frame = scene_meta.frames[frame_index+1]; setTimeout(function () {
setTimeout(
function(){
play_frame(scene_meta, next_frame, on_load_world_finished); play_frame(scene_meta, next_frame, on_load_world_finished);
}, }, 1000 / fps);
1000/fps); } else {
}
else{
scope.stop_play(); scope.stop_play();
} }
}); });
} else {
}
else{
//not ready. //not ready.
console.log("wait buffer!", frame); console.log("wait buffer!", frame);
setTimeout( setTimeout(function () {
function(){
play_frame(scene_meta, frame, on_load_world_finished); play_frame(scene_meta, frame, on_load_world_finished);
}, }, 10);
10); }
} }
} }
}; };
};
// function play_current_scene_without_buffer(){ // function play_current_scene_without_buffer(){
// if (!data.meta){ // if (!data.meta){
// console.log("no meta data! cannot play"); // console.log("no meta data! cannot play");
// return; // return;
// } // }
// if (stop_play_flag== false){
// return;
// }
// stop_play_flag = false;
// var scene_meta = data.get_current_world_scene_meta();
// var sceneName= scene_meta.scene;
// play_frame(scene_meta, data.world.frameInfo.frame); // if (stop_play_flag== false){
// return;
// }
// stop_play_flag = false;
// function play_frame(scene_meta, frame){ // var scene_meta = data.get_current_world_scene_meta();
// load_world(sceneName, frame); // var sceneName= scene_meta.scene;
// play_frame(scene_meta, data.world.frameInfo.frame);
// if (!stop_play_flag) // function play_frame(scene_meta, frame){
// { // load_world(sceneName, frame);
// var frame_index = scene_meta.frames.findIndex(function(x){return x == frame;});
// if (frame_index+1 < scene_meta.frames.length)
// {
// next_frame = scene_meta.frames[frame_index+1];
// setTimeout(
// function(){
// play_frame(scene_meta, next_frame);
// },
// 100);
// }
// else{
// stop_play_flag = true;
// }
// } // if (!stop_play_flag)
// }; // {
// } // var frame_index = scene_meta.frames.findIndex(function(x){return x == frame;});
// if (frame_index+1 < scene_meta.frames.length)
// {
// next_frame = scene_meta.frames[frame_index+1];
// setTimeout(
// function(){
// play_frame(scene_meta, next_frame);
// },
// 100);
// }
// else{
// stop_play_flag = true;
// }
// }
// };
// }
} }
export { PlayControl };
export {PlayControl};

@ -1,71 +1,58 @@
class MovableView {
class MovableView
{
mouseDown = false; mouseDown = false;
mouseDownPos = null; mouseDownPos = null;
// move starts in dragableUi, // move starts in dragableUi,
// movable in movableUi, // movable in movableUi,
// the pos of posUi is set. // the pos of posUi is set.
constructor(dragableUi, posUi, funcOnMove) constructor(dragableUi, posUi, funcOnMove) {
{
let movableUi = document.getElementById("move-handle-wrapper"); let movableUi = document.getElementById("move-handle-wrapper");
dragableUi.addEventListener("mousedown", (event)=>{ dragableUi.addEventListener("mousedown", (event) => {
if (event.which == 1 && event.currentTarget == event.target) if (event.which == 1 && event.currentTarget == event.target) {
{
this.mouseDown = true; this.mouseDown = true;
this.mouseDownPos = {x: event.clientX, y:event.clientY}; this.mouseDownPos = { x: event.clientX, y: event.clientY };
movableUi.style.display="inherit"; movableUi.style.display = "inherit";
} }
}); });
movableUi.addEventListener("mouseup", (event)=>{ movableUi.addEventListener("mouseup", (event) => {
if (this.mouseDown){ if (this.mouseDown) {
dragableUi.style.cursor = ""; dragableUi.style.cursor = "";
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
this.mouseDown = false; this.mouseDown = false;
movableUi.style.display="none"; movableUi.style.display = "none";
} }
}); });
movableUi.addEventListener("mousemove", (event)=>{ movableUi.addEventListener("mousemove", (event) => {
if (this.mouseDown) {
if (this.mouseDown){
let posDelta = { let posDelta = {
x: event.clientX - this.mouseDownPos.x, x: event.clientX - this.mouseDownPos.x,
y: event.clientY - this.mouseDownPos.y y: event.clientY - this.mouseDownPos.y,
}; };
dragableUi.style.cursor = "move"; dragableUi.style.cursor = "move";
this.mouseDownPos = {x: event.clientX, y:event.clientY}; this.mouseDownPos = { x: event.clientX, y: event.clientY };
let left = posUi.offsetLeft; let left = posUi.offsetLeft;
let top = posUi.offsetTop; let top = posUi.offsetTop;
posUi.style.left = Math.max(0, (left + posDelta.x)) + 'px'; posUi.style.left = Math.max(0, left + posDelta.x) + "px";
posUi.style.top = Math.max(0, (top + posDelta.y)) + 'px'; posUi.style.top = Math.max(0, top + posDelta.y) + "px";
if (funcOnMove) if (funcOnMove) funcOnMove();
funcOnMove();
} }
}); });
} }
} }
class PopupDialog extends MovableView {
class PopupDialog extends MovableView constructor(ui) {
{
constructor(ui)
{
super(ui.querySelector("#header"), ui.querySelector("#view")); super(ui.querySelector("#header"), ui.querySelector("#view"));
this.ui = ui; //wrapper this.ui = ui; //wrapper
@ -73,13 +60,12 @@ class PopupDialog extends MovableView
this.headerUi = this.ui.querySelector("#header"); this.headerUi = this.ui.querySelector("#header");
this.titleUi = this.ui.querySelector("#title"); this.titleUi = this.ui.querySelector("#title");
this.ui.onclick = ()=>{ this.ui.onclick = () => {
this.hide(); this.hide();
}; };
this.ui.addEventListener("keydown", (event)=>{ this.ui.addEventListener("keydown", (event) => {
if (event.key == "Escape") {
if (event.key == 'Escape'){
this.hide(); this.hide();
event.preventDefault(); event.preventDefault();
@ -87,50 +73,43 @@ class PopupDialog extends MovableView
event.stopPropagation(); event.stopPropagation();
}); });
this.viewUi.onclick = function(event){ this.viewUi.onclick = function (event) {
//event.preventDefault(); //event.preventDefault();
event.stopPropagation(); event.stopPropagation();
}; };
this.titleUi.onclick = function(event){ this.titleUi.onclick = function (event) {
//event.preventDefault(); //event.preventDefault();
event.stopPropagation(); event.stopPropagation();
}; };
this.titleUi.addEventListener("mousedown", (event)=>{ this.titleUi.addEventListener("mousedown", (event) => {
//event.preventDefault(); //event.preventDefault();
event.stopPropagation(); event.stopPropagation();
}); });
this.titleUi.addEventListener("contextmenu", (event)=>{ this.titleUi.addEventListener("contextmenu", (event) => {
event.stopPropagation(); event.stopPropagation();
}) });
// this.viewUi.addEventListener("contextmenu", (e)=>{ // this.viewUi.addEventListener("contextmenu", (e)=>{
// e.stopPropagation(); // e.stopPropagation();
// e.preventDefault(); // e.preventDefault();
// }); // });
// this.ui.querySelector("#info-view").onclick = function(event){ // this.ui.querySelector("#info-view").onclick = function(event){
// event.preventDefault(); // event.preventDefault();
// event.stopPropagation(); // event.stopPropagation();
// }; // };
this.ui.querySelector("#btn-exit").onclick = (event) => {
this.ui.querySelector("#btn-exit").onclick = (event)=>{
this.hide(); this.hide();
} };
this.maximizeButton = this.ui.querySelector("#btn-maximize") this.maximizeButton = this.ui.querySelector("#btn-maximize");
if (this.maximizeButton) if (this.maximizeButton) {
{ this.maximizeButton.onclick = (event) => {
this.maximizeButton.onclick = (event)=>{
let v = this.viewUi; let v = this.viewUi;
v.style.top = "0%"; v.style.top = "0%";
v.style.left = "0%"; v.style.left = "0%";
@ -138,7 +117,7 @@ class PopupDialog extends MovableView
v.style.height = "100%"; v.style.height = "100%";
v.style["z-index"] = 5; v.style["z-index"] = 5;
event.currentTarget.style.display = 'none'; event.currentTarget.style.display = "none";
this.ui.querySelector("#btn-restore").style.display = "inherit"; this.ui.querySelector("#btn-restore").style.display = "inherit";
}; };
} }
@ -146,40 +125,31 @@ class PopupDialog extends MovableView
this.restoreButton = this.ui.querySelector("#btn-restore"); this.restoreButton = this.ui.querySelector("#btn-restore");
if (this.restoreButton) { if (this.restoreButton) {
this.restoreButton.onclick = (event)=>{ this.restoreButton.onclick = (event) => {
let v = this.viewUi; let v = this.viewUi;
v.style.top = "20%"; v.style.top = "20%";
v.style.left = "20%"; v.style.left = "20%";
v.style.width = "60%"; v.style.width = "60%";
v.style.height = "60%"; v.style.height = "60%";
event.currentTarget.style.display = 'none'; event.currentTarget.style.display = "none";
this.ui.querySelector("#btn-maximize").style.display = "inherit"; this.ui.querySelector("#btn-maximize").style.display = "inherit";
}; };
} }
} }
hide(msg) {
this.ui.style.display = "none";
if (this.onExit) {
hide(msg)
{
this.ui.style.display = 'none';
if (this.onExit)
{
this.onExit(msg); this.onExit(msg);
} }
} }
show(onexit) show(onexit) {
{ this.ui.style.display = "inherit";
this.ui.style.display = 'inherit';
this.onExit = onexit; this.onExit = onexit;
//this.ui.focus(); //this.ui.focus();
} }
} }
export { PopupDialog, MovableView };
export {PopupDialog, MovableView}

@ -1,8 +1,8 @@
import * as THREE from './lib/three.module.js'; import * as THREE from "./lib/three.module.js";
import { PCDLoader } from './lib/PCDLoader.js'; import { PCDLoader } from "./lib/PCDLoader.js";
import { matmul, euler_angle_to_rotate_matrix_3by3} from "./util.js" import { matmul, euler_angle_to_rotate_matrix_3by3 } from "./util.js";
function Radar(sceneMeta, world, frameInfo, radarName){ function Radar(sceneMeta, world, frameInfo, radarName) {
this.world = world; this.world = world;
this.frameInfo = frameInfo; this.frameInfo = frameInfo;
this.name = radarName; this.name = radarName;
@ -11,11 +11,12 @@ function Radar(sceneMeta, world, frameInfo, radarName){
this.showPointsOnly = false; this.showPointsOnly = false;
this.showRadarBoxFlag = false; this.showRadarBoxFlag = false;
this.cssStyleSelector = this.sceneMeta.calib.radar[this.name].cssstyleselector; this.cssStyleSelector =
this.sceneMeta.calib.radar[this.name].cssstyleselector;
this.color = this.sceneMeta.calib.radar[this.name].color; this.color = this.sceneMeta.calib.radar[this.name].color;
this.velocityScale = 0.3; this.velocityScale = 0.3;
if (!this.color){ if (!this.color) {
this.color = [1.0, 0.0, 0.0]; this.color = [1.0, 0.0, 0.0];
} }
@ -25,27 +26,24 @@ function Radar(sceneMeta, world, frameInfo, radarName){
this.preloaded = false; this.preloaded = false;
this.loaded = false; this.loaded = false;
this.go_cmd_received = false; this.go_cmd_received = false;
this.webglScene = null; this.webglScene = null;
this.on_go_finished = null; this.on_go_finished = null;
this.go = function(webglScene, on_go_finished){ this.go = function (webglScene, on_go_finished) {
this.webglScene = webglScene; this.webglScene = webglScene;
if (this.preloaded){ if (this.preloaded) {
if (this.elements){ if (this.elements) {
this.webglScene.add(this.elements.points); this.webglScene.add(this.elements.points);
if (!this.showPointsOnly) if (!this.showPointsOnly)
this.elements.arrows.forEach(a=>this.webglScene.add(a)); this.elements.arrows.forEach((a) => this.webglScene.add(a));
if (this.showRadarBoxFlag) if (this.showRadarBoxFlag) this.webglScene.add(this.radar_box);
this.webglScene.add(this.radar_box);
} }
this.loaded = true; this.loaded = true;
if (on_go_finished) if (on_go_finished) on_go_finished();
on_go_finished();
} }
//anyway we save go cmd //anyway we save go cmd
@ -55,68 +53,64 @@ function Radar(sceneMeta, world, frameInfo, radarName){
} }
}; };
this.showRadarBox = function(){ this.showRadarBox = function () {
this.showRadarBoxFlag = true; this.showRadarBoxFlag = true;
this.webglScene.add(this.radar_box); this.webglScene.add(this.radar_box);
}; };
this.hideRadarBox = function(){ this.hideRadarBox = function () {
this.showRadarBoxFlag = false; this.showRadarBoxFlag = false;
this.webglScene.remove(this.radar_box); this.webglScene.remove(this.radar_box);
}; };
this.get_unoffset_radar_points = function(){ this.get_unoffset_radar_points = function () {
if (this.elements){ if (this.elements) {
let pts = this.elements.points.geometry.getAttribute("position").array; let pts = this.elements.points.geometry.getAttribute("position").array;
return pts.map((p,i)=>p-this.world.coordinatesOffset[i %3]); return pts.map((p, i) => p - this.world.coordinatesOffset[i % 3]);
} } else {
else{
return []; return [];
} }
}; };
// todo: what if it's not preloaded yet // todo: what if it's not preloaded yet
this.unload = function(keep_box){ this.unload = function (keep_box) {
if (this.elements){ if (this.elements) {
this.webglScene.remove(this.elements.points); this.webglScene.remove(this.elements.points);
if (!this.showPointsOnly) if (!this.showPointsOnly)
this.elements.arrows.forEach(a=>this.webglScene.remove(a)); this.elements.arrows.forEach((a) => this.webglScene.remove(a));
if (!keep_box) if (!keep_box) this.webglScene.remove(this.radar_box);
this.webglScene.remove(this.radar_box);
} }
this.loaded = false; this.loaded = false;
}; };
// todo: its possible to remove points before preloading, // todo: its possible to remove points before preloading,
this.deleteAll = function(keep_box){ this.deleteAll = function (keep_box) {
if (this.loaded){ if (this.loaded) {
this.unload(); this.unload();
} }
if (this.elements){ if (this.elements) {
//this.scene.remove(this.points); //this.scene.remove(this.points);
this.world.data.dbg.free(); this.world.data.dbg.free();
if (this.elements.points) if (this.elements.points) {
{
this.elements.points.geometry.dispose(); this.elements.points.geometry.dispose();
this.elements.points.material.dispose(); this.elements.points.material.dispose();
} }
if (this.elements.arrows) if (this.elements.arrows) {
{ this.elements.arrows.forEach((a) => {
this.elements.arrows.forEach(a=>{
this.world.data.dbg.free(); this.world.data.dbg.free();
a.geometry.dispose(); a.geometry.dispose();
a.material.dispose(); a.material.dispose();
}) });
} }
this.elements = null; this.elements = null;
} }
if (!keep_box && this.radar_box){ if (!keep_box && this.radar_box) {
this.world.data.dbg.free(); this.world.data.dbg.free();
this.radar_box.geometry.dispose(); this.radar_box.geometry.dispose();
this.radar_box.material.dispose(); this.radar_box.material.dispose();
@ -124,19 +118,21 @@ function Radar(sceneMeta, world, frameInfo, radarName){
} }
}; };
this.preload = function (on_preload_finished) {
this.preload = function(on_preload_finished){
var loader = new PCDLoader(); var loader = new PCDLoader();
var _self = this; var _self = this;
loader.load( this.frameInfo.get_radar_path(this.name), loader.load(
this.frameInfo.get_radar_path(this.name),
//ok //ok
function ( pcd ) { function (pcd) {
var position = pcd.position; var position = pcd.position;
//var velocity = pcd.velocity; //var velocity = pcd.velocity;
// velocity is a vector anchored at position, // velocity is a vector anchored at position,
// we translate them into position of the vector head // we translate them into position of the vector head
var velocity = position.map((p,i)=>pcd.velocity[i]+pcd.position[i]); var velocity = position.map(
(p, i) => pcd.velocity[i] + pcd.position[i]
);
// scale velocity // scale velocity
// velocity = velocity.map(v=>v*_self.velocityScale); // velocity = velocity.map(v=>v*_self.velocityScale);
@ -150,7 +146,7 @@ function Radar(sceneMeta, world, frameInfo, radarName){
_self.radar_box = _self.createRadarBox(); _self.radar_box = _self.createRadarBox();
// install callback for box changing // install callback for box changing
_self.radar_box.on_box_changed = ()=>{ _self.radar_box.on_box_changed = () => {
_self.move_radar(_self.radar_box); _self.move_radar(_self.radar_box);
}; };
@ -163,21 +159,20 @@ function Radar(sceneMeta, world, frameInfo, radarName){
//_self.points_backup = mesh; //_self.points_backup = mesh;
_self._afterPreload(); _self._afterPreload();
}, },
// on progress, // on progress,
function(){}, function () {},
// on error // on error
function(){ function () {
//error //error
console.log("load radar failed."); console.log("load radar failed.");
_self._afterPreload(); _self._afterPreload();
}, },
// on file loaded // on file loaded
function(){ function () {
//_self.points_readfile_time = new Date().getTime(); //_self.points_readfile_time = new Date().getTime();
//console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "read file ", _self.points_readfile_time - _self.create_time, "ms"); //console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "read file ", _self.points_readfile_time - _self.create_time, "ms");
} }
@ -185,151 +180,168 @@ function Radar(sceneMeta, world, frameInfo, radarName){
}; };
// internal funcs below // internal funcs below
this._afterPreload = function(){ this._afterPreload = function () {
this.preloaded = true; this.preloaded = true;
console.log(`radar ${this.radarname} preloaded`); console.log(`radar ${this.radarname} preloaded`);
if (this.on_preload_finished){ if (this.on_preload_finished) {
this.on_preload_finished(); this.on_preload_finished();
} }
if (this.go_cmd_received){ if (this.go_cmd_received) {
this.go(this.webglScene, this.on_go_finished); this.go(this.webglScene, this.on_go_finished);
} }
}; };
this.createRadarBox = function(){ this.createRadarBox = function () {
if (this.sceneMeta.calib.radar && this.sceneMeta.calib.radar[this.name]){ if (this.sceneMeta.calib.radar && this.sceneMeta.calib.radar[this.name]) {
return this.world.annotation.createCuboid( return this.world.annotation.createCuboid(
{ {
x: this.sceneMeta.calib.radar[this.name].translation[0] + this.coordinatesOffset[0], x:
y: this.sceneMeta.calib.radar[this.name].translation[1] + this.coordinatesOffset[1], this.sceneMeta.calib.radar[this.name].translation[0] +
z: this.sceneMeta.calib.radar[this.name].translation[2] + this.coordinatesOffset[2], this.coordinatesOffset[0],
y:
this.sceneMeta.calib.radar[this.name].translation[1] +
this.coordinatesOffset[1],
z:
this.sceneMeta.calib.radar[this.name].translation[2] +
this.coordinatesOffset[2],
}, },
{x:1,y:1, z:1}, { x: 1, y: 1, z: 1 },
{ {
x: this.sceneMeta.calib.radar[this.name].rotation[0], x: this.sceneMeta.calib.radar[this.name].rotation[0],
y: this.sceneMeta.calib.radar[this.name].rotation[1], y: this.sceneMeta.calib.radar[this.name].rotation[1],
z: this.sceneMeta.calib.radar[this.name].rotation[2], z: this.sceneMeta.calib.radar[this.name].rotation[2],
}, },
"radar", "radar",
this.name); this.name
);
}else { } else {
return this.world.annotation.createCuboid( return this.world.annotation.createCuboid(
{x: this.coordinatesOffset[0], {
x: this.coordinatesOffset[0],
y: this.coordinatesOffset[1], y: this.coordinatesOffset[1],
z: this.coordinatesOffset[2]}, z: this.coordinatesOffset[2],
{x:1,y:1, z:1}, },
{x:0,y:0,z:0}, { x: 1, y: 1, z: 1 },
{ x: 0, y: 0, z: 0 },
"radar", "radar",
this.name); this.name
);
} }
}; };
this.buildPoints = function(position){ this.buildPoints = function (position) {
// build geometry // build geometry
this.world.data.dbg.alloc(); this.world.data.dbg.alloc();
let geometry = new THREE.BufferGeometry(); let geometry = new THREE.BufferGeometry();
if ( position.length > 0 ) if (position.length > 0)
geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); geometry.addAttribute(
"position",
new THREE.Float32BufferAttribute(position, 3)
);
let pointColor = this.color; let pointColor = this.color;
let color=[]; let color = [];
for (var i =0; i< position.length; i+=3){ for (var i = 0; i < position.length; i += 3) {
color.push(pointColor[0]); color.push(pointColor[0]);
color.push(pointColor[1]); color.push(pointColor[1]);
color.push(pointColor[2]); color.push(pointColor[2]);
} }
geometry.addAttribute( 'color', new THREE.Float32BufferAttribute(color, 3 ) ); geometry.addAttribute("color", new THREE.Float32BufferAttribute(color, 3));
geometry.computeBoundingSphere(); geometry.computeBoundingSphere();
// build material // build material
let pointSize = this.sceneMeta.calib.radar[this.name].point_size; let pointSize = this.sceneMeta.calib.radar[this.name].point_size;
if (!pointSize) if (!pointSize) pointSize = 2;
pointSize = 2;
let material = new THREE.PointsMaterial( { size: pointSize, vertexColors: THREE.VertexColors } ); let material = new THREE.PointsMaterial({
size: pointSize,
vertexColors: THREE.VertexColors,
});
//material.size = 2; //material.size = 2;
material.sizeAttenuation = false; material.sizeAttenuation = false;
// build mesh // build mesh
let mesh = new THREE.Points( geometry, material ); let mesh = new THREE.Points(geometry, material);
mesh.name = "radar"; mesh.name = "radar";
return mesh; return mesh;
}; };
this.buildArrow = function(position, velocity){ this.buildArrow = function (position, velocity) {
var h = 0.5; var h = 0.5;
let p=position; let p = position;
let v=velocity; let v = velocity;
var body = [
p[0],p[1],p[2],
v[0],v[1],v[2],
];
var body = [p[0], p[1], p[2], v[0], v[1], v[2]];
this.world.data.dbg.alloc(); this.world.data.dbg.alloc();
var geo = new THREE.BufferGeometry(); var geo = new THREE.BufferGeometry();
geo.addAttribute( 'position', new THREE.Float32BufferAttribute(body, 3 ) ); geo.addAttribute("position", new THREE.Float32BufferAttribute(body, 3));
let color = this.color.map(c=>Math.round(c*255)).reduce((a,b)=>a*256+b, 0); let color = this.color
.map((c) => Math.round(c * 255))
.reduce((a, b) => a * 256 + b, 0);
var material = new THREE.LineBasicMaterial( { color: color, linewidth: 1, opacity: 1, transparent: true } ); var material = new THREE.LineBasicMaterial({
var arrow = new THREE.LineSegments( geo, material ); color: color,
linewidth: 1,
opacity: 1,
transparent: true,
});
var arrow = new THREE.LineSegments(geo, material);
return arrow; return arrow;
} };
this.buildRadarGeometry = function(position, velocity){ this.buildRadarGeometry = function (position, velocity) {
let points = this.buildPoints(position); let points = this.buildPoints(position);
let arrows = []; let arrows = [];
if (!this.showPointsOnly) if (!this.showPointsOnly) {
{ for (let i = 0; i < position.length / 3; i++) {
for (let i = 0; i<position.length/3; i++) let arr = this.buildArrow(
{ position.slice(i * 3, i * 3 + 3),
let arr = this.buildArrow(position.slice(i*3, i*3+3), velocity.slice(i*3, i*3+3)); velocity.slice(i * 3, i * 3 + 3)
);
arrows.push(arr); arrows.push(arr);
} }
} }
return { return {
points: points, points: points,
arrows: arrows arrows: arrows,
}; };
}; };
this.move_points = function(points, box){ this.move_points = function (points, box) {
let trans = euler_angle_to_rotate_matrix_3by3(box.rotation); let trans = euler_angle_to_rotate_matrix_3by3(box.rotation);
let rotated_points = matmul(trans, points, 3); let rotated_points = matmul(trans, points, 3);
let translation=[box.position.x, box.position.y, box.position.z]; let translation = [box.position.x, box.position.y, box.position.z];
let translated_points = rotated_points.map((p,i)=>{ let translated_points = rotated_points.map((p, i) => {
return p + translation[i % 3]; return p + translation[i % 3];
}); });
return translated_points; return translated_points;
}; };
this.move_radar_points = function(box){ this.move_radar_points = function (box) {
return this.move_points(this._radar_points_raw, box); return this.move_points(this._radar_points_raw, box);
}; };
this.move_radar_velocity = function(box){ this.move_radar_velocity = function (box) {
return this.move_points(this._radar_velocity_raw, box); return this.move_points(this._radar_velocity_raw, box);
} };
this.move_radar= function(box){
this.move_radar = function (box) {
let translated_points = this.move_radar_points(box); let translated_points = this.move_radar_points(box);
let translated_velocity = this.move_radar_velocity(box); let translated_velocity = this.move_radar_velocity(box);
let elements = this.buildRadarGeometry(translated_points, translated_velocity); let elements = this.buildRadarGeometry(
translated_points,
translated_velocity
);
// remove old points // remove old points
this.unload(true); this.unload(true);
@ -337,82 +349,75 @@ function Radar(sceneMeta, world, frameInfo, radarName){
this.elements = elements; this.elements = elements;
//_self.points_backup = mesh; //_self.points_backup = mesh;
if (this.go_cmd_received) // this should be always true if (this.go_cmd_received) {
{ // this should be always true
this.webglScene.add(this.elements.points); this.webglScene.add(this.elements.points);
if (!this.showPointsOnly) if (!this.showPointsOnly)
this.elements.arrows.forEach(a=>this.webglScene.add(a)); this.elements.arrows.forEach((a) => this.webglScene.add(a));
} }
}; };
} }
function RadarManager(sceneMeta, world, frameInfo){ function RadarManager(sceneMeta, world, frameInfo) {
this.radarList = []; this.radarList = [];
if (world.data.cfg.enableRadar && sceneMeta.radar){ if (world.data.cfg.enableRadar && sceneMeta.radar) {
let radars = []; let radars = [];
for (let r in sceneMeta.calib.radar){ for (let r in sceneMeta.calib.radar) {
if (!sceneMeta.calib.radar[r].disable) if (!sceneMeta.calib.radar[r].disable) radars.push(r);
radars.push(r);
} }
this.radarList = radars.map(name=>{ this.radarList = radars.map((name) => {
return new Radar(sceneMeta, world, frameInfo, name); return new Radar(sceneMeta, world, frameInfo, name);
}); });
} }
this.getAllBoxes = function() this.getAllBoxes = function () {
{ if (this.showRadarBoxFlag) {
if (this.showRadarBoxFlag) return this.radarList.map((r) => r.radar_box);
{ } else {
return this.radarList.map(r=>r.radar_box);
}
else
{
return []; return [];
} }
}; };
this.preloaded = function(){ this.preloaded = function () {
for (let r in this.radarList){ for (let r in this.radarList) {
if (!this.radarList[r].preloaded) if (!this.radarList[r].preloaded) return false;
return false;
} }
return true; return true;
}; };
this.go = function(webglScene, on_go_finished){ this.go = function (webglScene, on_go_finished) {
this.radarList.forEach(r=>r.go(webglScene, on_go_finished)); this.radarList.forEach((r) => r.go(webglScene, on_go_finished));
}; };
this.preload = function(on_preload_finished){ this.preload = function (on_preload_finished) {
this.radarList.forEach(r=>r.preload(on_preload_finished)); this.radarList.forEach((r) => r.preload(on_preload_finished));
}; };
this.unload = function(){ this.unload = function () {
this.radarList.forEach(r=>r.unload()); this.radarList.forEach((r) => r.unload());
}; };
this.deleteAll = function(){ this.deleteAll = function () {
this.radarList.forEach(r=>r.deleteAll()); this.radarList.forEach((r) => r.deleteAll());
}; };
this.getOperableObjects = function(){ this.getOperableObjects = function () {
return this.radarList.flatMap(r=>r.getOperableObjects()); return this.radarList.flatMap((r) => r.getOperableObjects());
}; };
this.showRadarBoxFlag = false; this.showRadarBoxFlag = false;
this.showRadarBox = function(){ this.showRadarBox = function () {
this.showRadarBoxFlag = true; this.showRadarBoxFlag = true;
this.radarList.forEach(r=>r.showRadarBox()); this.radarList.forEach((r) => r.showRadarBox());
}; };
this.hideRadarBox = function(){ this.hideRadarBox = function () {
this.showRadarBoxFlag = false; this.showRadarBoxFlag = false;
this.radarList.forEach(r=>r.hideRadarBox()); this.radarList.forEach((r) => r.hideRadarBox());
} };
}; }
export {RadarManager} export { RadarManager };

@ -1,14 +1,13 @@
import * as THREE from './lib/three.module.js'; import * as THREE from "./lib/three.module.js";
import { PCDLoader } from './lib/PCDLoader.js'; import { PCDLoader } from "./lib/PCDLoader.js";
import { OrbitControls } from './lib/OrbitControls.js'; import { OrbitControls } from "./lib/OrbitControls.js";
import { GUI } from './lib/dat.gui.module.js'; import { GUI } from "./lib/dat.gui.module.js";
import {TextFileLoader} from "./text_file_loader.js"; import { TextFileLoader } from "./text_file_loader.js";
var container, stats; var container, stats;
var camera, controls, scene, renderer; var camera, controls, scene, renderer;
var camera; var camera;
var params = { var params = {
src: true, src: true,
tgt: true, tgt: true,
@ -20,62 +19,58 @@ var last_cloud_ind = {
src: true, src: true,
tgt: true, tgt: true,
out: true, out: true,
} };
var clouds ={}; var clouds = {};
init(); init();
animate(); animate();
function init() { function init() {
document.body.addEventListener('keydown', event => { document.body.addEventListener("keydown", (event) => {
if (event.ctrlKey && 'asdv'.indexOf(event.key) !== -1) { if (event.ctrlKey && "asdv".indexOf(event.key) !== -1) {
event.preventDefault() event.preventDefault();
} }
}) });
scene = new THREE.Scene(); scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
camera = new THREE.PerspectiveCamera(
renderer = new THREE.WebGLRenderer( { antialias: true } ); 65,
renderer.setPixelRatio( window.devicePixelRatio ); window.innerWidth / window.innerHeight,
1,
800
);
camera = new THREE.PerspectiveCamera( 65, window.innerWidth / window.innerHeight, 1, 800 );
camera.position.x = 0; camera.position.x = 0;
camera.position.z = 50; camera.position.z = 50;
camera.position.y = 0; camera.position.y = 0;
camera.up.set( 0, 0, 1); camera.up.set(0, 0, 1);
camera.lookAt( 0, 0, 0 ); camera.lookAt(0, 0, 0);
controls = new OrbitControls( camera, renderer.domElement ); controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop) controls.addEventListener("change", render); // call this only in static scenes (i.e., if there is no animation loop)
container = document.createElement( 'container' ); container = document.createElement("container");
document.body.appendChild(container);
container.appendChild(renderer.domElement);
document.body.appendChild( container ); document.addEventListener("keydown", keydown);
container.appendChild( renderer.domElement );
document.addEventListener("keydown", keydown)
init_gui(); init_gui();
//scene.add( new THREE.AxesHelper( 2 ) ); //scene.add( new THREE.AxesHelper( 2 ) );
onWindowResize(); onWindowResize();
window.addEventListener( 'resize', onWindowResize, false ); window.addEventListener("resize", onWindowResize, false);
load_all(); load_all();
render(); render();
} }
function load_all(){ function load_all() {
clearAll(); clearAll();
load_pcd("src", "/temp/src.pcd", 0xff0000); load_pcd("src", "/temp/src.pcd", 0xff0000);
load_pcd("tgt", "/temp/tgt.pcd", 0x00ff00); load_pcd("tgt", "/temp/tgt.pcd", 0x00ff00);
@ -83,8 +78,7 @@ function load_all(){
load_transform_matrix(); load_transform_matrix();
} }
function clearAll(){ function clearAll() {
remove(clouds["src"]); remove(clouds["src"]);
remove(clouds["tgt"]); remove(clouds["tgt"]);
remove(clouds["out"]); remove(clouds["out"]);
@ -93,8 +87,8 @@ function clearAll(){
clouds["tgt"] = null; clouds["tgt"] = null;
clouds["our"] = null; clouds["our"] = null;
function remove(p){ function remove(p) {
if (p){ if (p) {
scene.remove(p); scene.remove(p);
p.geometry.dispose(); p.geometry.dispose();
p.material.dispose(); p.material.dispose();
@ -102,16 +96,14 @@ function clearAll(){
} }
} }
function keydown(ev) {
function keydown( ev ) { switch (ev.key) {
case "+":
switch ( ev.key) {
case '+':
clouds["src"].material.size *= 1.2; clouds["src"].material.size *= 1.2;
clouds["tgt"].material.size *= 1.2; clouds["tgt"].material.size *= 1.2;
clouds["out"].material.size *= 1.2; clouds["out"].material.size *= 1.2;
break; break;
case '-': case "-":
clouds["src"].material.size /= 1.2; clouds["src"].material.size /= 1.2;
clouds["tgt"].material.size /= 1.2; clouds["tgt"].material.size /= 1.2;
clouds["out"].material.size /= 1.2; clouds["out"].material.size /= 1.2;
@ -120,115 +112,115 @@ function keydown( ev ) {
} }
} }
function onWindowResize() { function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight; camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setSize(window.innerWidth, window.innerHeight);
} }
function animate() { function animate() {
requestAnimationFrame( animate ); requestAnimationFrame(animate);
controls.update(); controls.update();
render(); render();
switch_cloud("src"); switch_cloud("src");
switch_cloud("tgt"); switch_cloud("tgt");
switch_cloud("out"); switch_cloud("out");
function switch_cloud(name){ function switch_cloud(name) {
if (params[name] != last_cloud_ind[name]){ if (params[name] != last_cloud_ind[name]) {
last_cloud_ind[name] = params[name]; last_cloud_ind[name] = params[name];
if (last_cloud_ind[name]){ if (last_cloud_ind[name]) {
scene.add(clouds[name]); scene.add(clouds[name]);
}else { } else {
scene.remove(clouds[name]); scene.remove(clouds[name]);
} }
} }
} }
} }
function render() {
function render(){ renderer.render(scene, camera);
renderer.render( scene, camera );
} }
function load_transform_matrix(){ function load_transform_matrix() {
var loader = new TextFileLoader(); var loader = new TextFileLoader();
loader.load( "/temp/trans.json", loader.load("/temp/trans.json", function (json) {
function(json){
console.log(json); console.log(json);
var mat = JSON.parse(json); var mat = JSON.parse(json);
var trans_html = "<table><tbody>"; var trans_html = "<table><tbody>";
for (var i = 0; i<4; i++){ for (var i = 0; i < 4; i++) {
trans_html += "<tr>"; trans_html += "<tr>";
for (var j =0; j<4; j++) for (var j = 0; j < 4; j++)
trans_html += "<td>"+ mat[i*4+j] + "</td>"; trans_html += "<td>" + mat[i * 4 + j] + "</td>";
trans_html += "</tr>" trans_html += "</tr>";
} }
trans_html += "</tbody></table>"; trans_html += "</tbody></table>";
document.getElementById("info").innerHTML = trans_html; document.getElementById("info").innerHTML = trans_html;
} });
)
} }
function load_pcd(name, file, overall_color){ function load_pcd(name, file, overall_color) {
var loader = new PCDLoader(); var loader = new PCDLoader();
loader.load( file, loader.load(file, function (pcd) {
function ( pcd ) {
var position = pcd.position; var position = pcd.position;
var color = pcd.color; var color = pcd.color;
var normal = pcd.normal; var normal = pcd.normal;
// build geometry // build geometry
var geometry = new THREE.BufferGeometry(); var geometry = new THREE.BufferGeometry();
if ( position.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); if (position.length > 0)
if ( normal.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal, 3 ) ); geometry.addAttribute(
if ( color.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) ); "position",
new THREE.Float32BufferAttribute(position, 3)
);
if (normal.length > 0)
geometry.addAttribute(
"normal",
new THREE.Float32BufferAttribute(normal, 3)
);
if (color.length > 0)
geometry.addAttribute(
"color",
new THREE.Float32BufferAttribute(color, 3)
);
geometry.computeBoundingSphere(); geometry.computeBoundingSphere();
// build material // build material
var material = new THREE.PointsMaterial( { size: 0.005 } ); var material = new THREE.PointsMaterial({ size: 0.005 });
if ( color.length > 0 ) { if (color.length > 0) {
material.vertexColors = VertexColors; material.vertexColors = VertexColors;
} else { } else {
material.color.setHex(overall_color ); material.color.setHex(overall_color);
} }
//material.size = 0.1; //material.size = 0.1;
// build mesh // build mesh
var mesh = new THREE.Points( geometry, material ); var mesh = new THREE.Points(geometry, material);
mesh.name = "pcd"; mesh.name = "pcd";
//return mesh; //return mesh;
if (params[name]) if (params[name]) scene.add(mesh);
scene.add(mesh);
clouds[name] = mesh; clouds[name] = mesh;
//var center = points.geometry.boundingSphere.center; //var center = points.geometry.boundingSphere.center;
//controls.target.set( center.x, center.y, center.z ); //controls.target.set( center.x, center.y, center.z );
//controls.update(); //controls.update();
}, });
);
} }
function init_gui() {
function init_gui(){
var gui = new GUI(); var gui = new GUI();
var cfgFolder = gui.addFolder( 'View' ); var cfgFolder = gui.addFolder("View");
cfgFolder.add( params, "src"); cfgFolder.add(params, "src");
cfgFolder.add( params, "tgt"); cfgFolder.add(params, "tgt");
cfgFolder.add( params, "out"); cfgFolder.add(params, "out");
cfgFolder.add( params, "reload"); cfgFolder.add(params, "reload");
cfgFolder.open(); cfgFolder.open();
gui.open(); gui.open();
} }

@ -1,14 +1,8 @@
import { Editor } from "./editor.js"; import { Editor } from "./editor.js";
import { checkScene } from "./error_check.js"; import { checkScene } from "./error_check.js";
import {logger} from "./log.js" import { logger } from "./log.js";
function reloadWorldList(worldList, done) {
function reloadWorldList(worldList, done){
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
// we defined the xhr // we defined the xhr
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
@ -18,28 +12,24 @@ function reloadWorldList(worldList, done){
let anns = JSON.parse(this.responseText); let anns = JSON.parse(this.responseText);
// load annotations // load annotations
anns.forEach(a=>{ anns.forEach((a) => {
let world = worldList.find(w=>{ let world = worldList.find((w) => {
return (w.frameInfo.scene == a.scene && return w.frameInfo.scene == a.scene && w.frameInfo.frame == a.frame;
w.frameInfo.frame == a.frame);
}); });
if (world){ if (world) {
world.annotation.reapplyAnnotation(a.annotation); world.annotation.reapplyAnnotation(a.annotation);
} } else {
else{
console.error("bug?"); console.error("bug?");
} }
}); });
if (done) if (done) done();
done();
} }
}; };
xhr.open('POST', "/loadworldlist", true); xhr.open("POST", "/loadworldlist", true);
let para = worldList.map(w=>{ let para = worldList.map((w) => {
return { return {
//todo: we could add an id, so as to associate world easily //todo: we could add an id, so as to associate world easily
scene: w.frameInfo.scene, scene: w.frameInfo.scene,
@ -50,33 +40,28 @@ function reloadWorldList(worldList, done){
xhr.send(JSON.stringify(para)); xhr.send(JSON.stringify(para));
} }
var saveDelayTimer = null; var saveDelayTimer = null;
var pendingSaveList = []; var pendingSaveList = [];
function saveWorldList(worldList){ function saveWorldList(worldList) {
//pendingSaveList = pendingSaveList.concat(worldList); //pendingSaveList = pendingSaveList.concat(worldList);
worldList.forEach(w=>{ worldList.forEach((w) => {
if (!pendingSaveList.includes(w)) if (!pendingSaveList.includes(w)) pendingSaveList.push(w);
pendingSaveList.push(w);
}); });
if (saveDelayTimer) if (saveDelayTimer) {
{
clearTimeout(saveDelayTimer); clearTimeout(saveDelayTimer);
} }
saveDelayTimer = setTimeout(()=>{ saveDelayTimer = setTimeout(
() => {
logger.log("save delay expired."); logger.log("save delay expired.");
//pandingSaveList will be cleared soon. //pandingSaveList will be cleared soon.
let scene = pendingSaveList[0].frameInfo.scene; let scene = pendingSaveList[0].frameInfo.scene;
doSaveWorldList(pendingSaveList, () => {
doSaveWorldList(pendingSaveList, ()=>{
editor.header.updateModifiedStatus(); editor.header.updateModifiedStatus();
checkScene(scene); checkScene(scene);
@ -86,56 +71,57 @@ function saveWorldList(worldList){
saveDelayTimer = null; saveDelayTimer = null;
pendingSaveList = []; pendingSaveList = [];
}, },
500); 500
);
} }
function doSaveWorldList(worldList, done) {
function doSaveWorldList(worldList, done) if (worldList.length > 0) {
{ if (worldList[0].data.cfg.disableLabels) {
if (worldList.length>0){ console.log("labels not loaded, save action is prohibitted.");
if (worldList[0].data.cfg.disableLabels){
console.log("labels not loaded, save action is prohibitted.")
return; return;
} }
} }
console.log(worldList.length, "frames"); console.log(worldList.length, "frames");
let ann = worldList.map(w=>{ let ann = worldList.map((w) => {
return { return {
scene: w.frameInfo.scene, scene: w.frameInfo.scene,
frame: w.frameInfo.frame, frame: w.frameInfo.frame,
annotation: w.annotation.toBoxAnnotations(), annotation: w.annotation.toBoxAnnotations(),
}; };
}) });
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open("POST", "/saveworldlist", true); xhr.open("POST", "/saveworldlist", true);
xhr.setRequestHeader('Content-Type', 'application/json'); xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
if (this.readyState != 4) return; if (this.readyState != 4) return;
if (this.status == 200) { if (this.status == 200) {
worldList.forEach((w) => {
worldList.forEach(w=>{
w.annotation.resetModified(); w.annotation.resetModified();
}) });
logger.log(`saved: ${worldList[0].frameInfo.scene}: ${worldList.reduce((a,b)=>a+" "+b.frameInfo.frame, "")}`); logger.log(
`saved: ${worldList[0].frameInfo.scene}: ${worldList.reduce(
(a, b) => a + " " + b.frameInfo.frame,
""
)}`
);
if(done){ if (done) {
done(); done();
} }
} else {
window.editor.infoBox.show(
"Error",
`save failed, status : ${this.status}`
);
} }
else{
window.editor.infoBox.show("Error", `save failed, status : ${this.status}`);
}
// end of state change: it can be after some time (async) // end of state change: it can be after some time (async)
}; };
@ -173,8 +159,6 @@ function doSaveWorldList(worldList, done)
// done(); // done();
// } // }
// } // }
// // end of state change: it can be after some time (async) // // end of state change: it can be after some time (async)
@ -185,5 +169,4 @@ function doSaveWorldList(worldList, done)
// xhr.send(b); // xhr.send(b);
// } // }
export { saveWorldList, reloadWorldList };
export {saveWorldList, reloadWorldList}

@ -1,7 +1,6 @@
var settings= { var settings = {
ground_filter_height: 0.2, ground_filter_height: 0.2,
initial_z_position: -0.9, initial_z_position: -0.9,
};
} export { settings };
export {settings}

File diff suppressed because it is too large Load Diff

@ -1,80 +1,84 @@
import * as THREE from "./lib/three.module.js";
import * as THREE from './lib/three.module.js';
//import Stats from './lib/stats.module.js'; //import Stats from './lib/stats.module.js';
import { OrthographicTrackballControls } from './lib/OrthographicTrackballControls.js'; import { OrthographicTrackballControls } from "./lib/OrthographicTrackballControls.js";
var camera, controls, scene, renderer, stats; var camera, controls, scene, renderer, stats;
init(); init();
animate(); animate();
function init() { function init() {
camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 2000 ); camera = new THREE.OrthographicCamera(
window.innerWidth / -2,
window.innerWidth / 2,
window.innerHeight / 2,
window.innerHeight / -2,
1,
2000
);
camera.position.z = 1000; camera.position.z = 1000;
// world // world
scene = new THREE.Scene(); scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc ); scene.background = new THREE.Color(0xcccccc);
scene.fog = new THREE.FogExp2( 0xcccccc, 0.001 ); scene.fog = new THREE.FogExp2(0xcccccc, 0.001);
var geometry = new THREE.CylinderBufferGeometry( 0, 10, 30, 4, 1 ); var geometry = new THREE.CylinderBufferGeometry(0, 10, 30, 4, 1);
var material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } ); var material = new THREE.MeshPhongMaterial({
for ( var i = 0; i < 50; i ++ ) { color: 0xffffff,
var mesh = new THREE.Mesh( geometry, material ); flatShading: true,
mesh.position.x = ( Math.random() - 0.5 ) * 1000; });
mesh.position.y = ( Math.random() - 0.5 ) * 1000; for (var i = 0; i < 50; i++) {
mesh.position.z = ( Math.random() - 0.5 ) * 1000; var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = (Math.random() - 0.5) * 1000;
mesh.position.y = (Math.random() - 0.5) * 1000;
mesh.position.z = (Math.random() - 0.5) * 1000;
mesh.updateMatrix(); mesh.updateMatrix();
mesh.matrixAutoUpdate = false; mesh.matrixAutoUpdate = false;
scene.add( mesh ); scene.add(mesh);
} }
// lights // lights
var light = new THREE.DirectionalLight( 0xffffff ); var light = new THREE.DirectionalLight(0xffffff);
light.position.set( 1, 1, 1 ); light.position.set(1, 1, 1);
scene.add( light ); scene.add(light);
var light = new THREE.DirectionalLight( 0x002288 ); var light = new THREE.DirectionalLight(0x002288);
light.position.set( - 1, - 1, - 1 ); light.position.set(-1, -1, -1);
scene.add( light ); scene.add(light);
var light = new THREE.AmbientLight( 0x222222 ); var light = new THREE.AmbientLight(0x222222);
scene.add( light ); scene.add(light);
// renderer // renderer
renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio( window.devicePixelRatio ); renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild( renderer.domElement ); document.body.appendChild(renderer.domElement);
controls = new OrthographicTrackballControls(camera, renderer.domElement);
controls = new OrthographicTrackballControls( camera, renderer.domElement );
controls.rotateSpeed = 1.0; controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2; controls.zoomSpeed = 1.2;
controls.noZoom = false; controls.noZoom = false;
controls.noPan = false; controls.noPan = false;
controls.staticMoving = true; controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3; controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ]; controls.keys = [65, 83, 68];
controls.addEventListener( 'change', render ); controls.addEventListener("change", render);
//stats = new Stats(); //stats = new Stats();
//document.body.appendChild( stats.dom ); //document.body.appendChild( stats.dom );
// //
window.addEventListener( 'resize', onWindowResize, false ); window.addEventListener("resize", onWindowResize, false);
// //
render(); render();
} }
function onWindowResize() { function onWindowResize() {
camera.left = window.innerWidth / - 2; camera.left = window.innerWidth / -2;
camera.right = window.innerWidth / 2; camera.right = window.innerWidth / 2;
camera.top = window.innerHeight / 2; camera.top = window.innerHeight / 2;
camera.bottom = window.innerHeight / - 2; camera.bottom = window.innerHeight / -2;
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setSize(window.innerWidth, window.innerHeight);
controls.handleResize(); controls.handleResize();
render(); render();
} }
function animate() { function animate() {
requestAnimationFrame( animate ); requestAnimationFrame(animate);
controls.update(); controls.update();
//stats.update(); //stats.update();
} }
function render() { function render() {
renderer.render( scene, camera ); renderer.render(scene, camera);
} }

@ -1,56 +1,45 @@
import { import {
DefaultLoadingManager, DefaultLoadingManager,
FileLoader, FileLoader,
LoaderUtils, LoaderUtils,
} from "./lib/three.module.js"; } from "./lib/three.module.js";
var TextFileLoader = function ( manager ) { var TextFileLoader = function (manager) {
this.manager = manager !== undefined ? manager : DefaultLoadingManager;
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
this.littleEndian = true; this.littleEndian = true;
}; };
TextFileLoader.prototype = { TextFileLoader.prototype = {
constructor: TextFileLoader, constructor: TextFileLoader,
load: function ( url, onLoad, onProgress, onError ) { load: function (url, onLoad, onProgress, onError) {
var scope = this; var scope = this;
var loader = new FileLoader( scope.manager ); var loader = new FileLoader(scope.manager);
loader.setPath( scope.path ); loader.setPath(scope.path);
loader.setResponseType( 'arraybuffer' ); loader.setResponseType("arraybuffer");
loader.load( url, function ( data ) { loader.load(
url,
function (data) {
try { try {
var textData = LoaderUtils.decodeText( new Uint8Array( data ) ); var textData = LoaderUtils.decodeText(new Uint8Array(data));
onLoad(textData, url); onLoad(textData, url);
} catch ( e ) { } catch (e) {
if (onError) {
if ( onError ) { onError(e);
onError( e );
} else { } else {
throw e; throw e;
} }
} }
},
}, onProgress, onError ); onProgress,
onError
);
}, },
setPath: function ( value ) { setPath: function (value) {
this.path = value; this.path = value;
return this; return this;
}, },
}; };

@ -1,62 +1,52 @@
import { PopupDialog } from "./popup_dialog.js"; import { PopupDialog } from "./popup_dialog.js";
class Trajectory extends PopupDialog {
class Trajectory extends PopupDialog{
mouseDown = false; mouseDown = false;
constructor(ui) {
constructor(ui)
{
super(ui); super(ui);
this.ui = ui; this.ui = ui;
this.ui.addEventListener("keydown", (event) => {
//anykey
this.ui.addEventListener("keydown", (event)=>{ //anykey if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
if (!event.ctrlKey && !event.shiftKey && !event.altKey)
{
this.hide(); this.hide();
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
} }
}); });
this.tracksUi = this.ui.querySelector("#svg-arrows"); this.tracksUi = this.ui.querySelector("#svg-arrows");
this.svgUi = this.ui.querySelector("#object-track-svg"); this.svgUi = this.ui.querySelector("#object-track-svg");
this.svgUi.addEventListener("wheel", (event)=>{ this.svgUi.addEventListener("wheel", (event) => {
console.log("wheel", event.wheelDelta); console.log("wheel", event.wheelDelta);
let scaleRatio = event.wheelDelta / 2400;
let scaleRatio = event.wheelDelta/2400; if (event.ctrlKey) {
this.objScale *= 1 + scaleRatio;
if (event.ctrlKey) } else {
{ let clientLength = Math.min(
this.objScale *= 1 + (scaleRatio); this.svgUi.clientWidth,
} this.svgUi.clientHeight
else );
{
let clientLength = Math.min(this.svgUi.clientWidth, this.svgUi.clientHeight);
let currentTargetRect = event.currentTarget.getBoundingClientRect(); let currentTargetRect = event.currentTarget.getBoundingClientRect();
let eventOffsetX = event.pageX - currentTargetRect.left; let eventOffsetX = event.pageX - currentTargetRect.left;
let eventOffsetY = event.pageY - currentTargetRect.top; let eventOffsetY = event.pageY - currentTargetRect.top;
let x = eventOffsetX/clientLength*1000; let x = (eventOffsetX / clientLength) * 1000;
let y = eventOffsetY/clientLength*1000; let y = (eventOffsetY / clientLength) * 1000;
this.posTrans.x = x - (x-this.posTrans.x) * (1+scaleRatio); this.posTrans.x = x - (x - this.posTrans.x) * (1 + scaleRatio);
this.posTrans.y = y - (y-this.posTrans.y) * (1+scaleRatio); this.posTrans.y = y - (y - this.posTrans.y) * (1 + scaleRatio);
this.posScale *= 1 + scaleRatio;
this.posScale *= 1 + (scaleRatio);
} }
this.redrawAll(); this.redrawAll();
event.preventDefault(); event.preventDefault();
@ -67,64 +57,62 @@ class Trajectory extends PopupDialog{
this.inMovingCanvas = false; this.inMovingCanvas = false;
this.startPosForMovingCanvas = {}; this.startPosForMovingCanvas = {};
this.svgUi.addEventListener("mousedown", (event)=>{ this.svgUi.addEventListener("mousedown", (event) => {
this.inMovingCanvas = true; this.inMovingCanvas = true;
this.startPosForMovingCanvas = {x: event.pageX, y:event.pageY}; this.startPosForMovingCanvas = { x: event.pageX, y: event.pageY };
}); });
this.svgUi.addEventListener("mouseup", (event)=>{ this.svgUi.addEventListener("mouseup", (event) => {
this.inMovingCanvas = false; this.inMovingCanvas = false;
}); });
this.svgUi.addEventListener("mousemove", (event)=>{ this.svgUi.addEventListener("mousemove", (event) => {
if (this.inMovingCanvas) if (this.inMovingCanvas) {
{
let delta = { let delta = {
x: event.pageX - this.startPosForMovingCanvas.x, x: event.pageX - this.startPosForMovingCanvas.x,
y: event.pageY - this.startPosForMovingCanvas.y y: event.pageY - this.startPosForMovingCanvas.y,
}; };
let clientLength = Math.min(this.svgUi.clientWidth, this.svgUi.clientHeight); let clientLength = Math.min(
this.svgUi.clientWidth,
this.svgUi.clientHeight
);
this.posTrans.x += delta.x / clientLength * 1000; this.posTrans.x += (delta.x / clientLength) * 1000;
this.posTrans.y += delta.y / clientLength * 1000; this.posTrans.y += (delta.y / clientLength) * 1000;
this.startPosForMovingCanvas = {x: event.pageX, y:event.pageY}; this.startPosForMovingCanvas = { x: event.pageX, y: event.pageY };
this.redrawAll(); this.redrawAll();
} }
}); });
this.resizeObserver = new ResizeObserver((elements) => {
this.resizeObserver = new ResizeObserver(elements=>{ if (elements[0].contentRect.height == 0) return;
if (elements[0].contentRect.height == 0)
return;
this.redrawAll(); this.redrawAll();
}); });
this.resizeObserver.observe(this.viewUi); this.resizeObserver.observe(this.viewUi);
} }
viewScale = 1; viewScale = 1;
objScale = 1; objScale = 1;
updateObjectScale() updateObjectScale() {
{
let v = this.viewUi; let v = this.viewUi;
this.viewScale = Math.max(1000/v.clientHeight, 1000/v.clientWidth); this.viewScale = Math.max(1000 / v.clientHeight, 1000 / v.clientWidth);
} }
object = {}; object = {};
setObject(
setObject(objType, objId, tracks, funcOnExit) //tracks is a list of [frameId, x, y, direction], in order objType,
{ objId,
tracks,
funcOnExit //tracks is a list of [frameId, x, y, direction], in order
) {
this.object = { this.object = {
type: objType, type: objType,
id: objId, id: objId,
tracks:tracks tracks: tracks,
}; };
this.funcOnExit = funcOnExit; this.funcOnExit = funcOnExit;
@ -135,8 +123,7 @@ class Trajectory extends PopupDialog{
this.ui.focus(); this.ui.focus();
} }
redrawAll() redrawAll() {
{
this.show(); this.show();
this.clear(); this.clear();
this.updateObjectScale(); this.updateObjectScale();
@ -146,22 +133,19 @@ class Trajectory extends PopupDialog{
this.drawScaler(); this.drawScaler();
} }
clear() {
clear(){
let arrows = this.ui.querySelector("#svg-arrows").children; let arrows = this.ui.querySelector("#svg-arrows").children;
if (arrows.length>0){ if (arrows.length > 0) {
for (var c=arrows.length-1; c >= 0; c--){ for (var c = arrows.length - 1; c >= 0; c--) {
arrows[c].remove(); arrows[c].remove();
} }
} }
let scaler = this.ui.querySelector("#svg-scaler").children; let scaler = this.ui.querySelector("#svg-scaler").children;
if (scaler.length>0){ if (scaler.length > 0) {
for (var c=scaler.length-1; c >= 0; c--){ for (var c = scaler.length - 1; c >= 0; c--) {
scaler[c].remove(); scaler[c].remove();
} }
} }
@ -180,61 +164,55 @@ class Trajectory extends PopupDialog{
y goes north (up) y goes north (up)
*/ */
calculateCoordinateTransform(tracks) calculateCoordinateTransform(tracks) {
{ tracks = tracks.filter((x) => x[1]);
tracks = tracks.filter(x=>x[1]); let xs = tracks.map((x) => x[1].psr.position.x);
let xs = tracks.map(x=> x[1].psr.position.x); let max_x = Math.max(...xs); //, 0);
let max_x = Math.max(...xs);//, 0); let min_x = Math.min(...xs); //, 0);
let min_x = Math.min(...xs);//, 0);
let ys = tracks.map(x=> x[1].psr.position.y); let ys = tracks.map((x) => x[1].psr.position.y);
let max_y = Math.max(...ys);//, 0); let max_y = Math.max(...ys); //, 0);
let min_y = Math.min(...ys);//, 0); let min_y = Math.min(...ys); //, 0);
let scale = Math.max(max_x - min_x, max_y - min_y); let scale = Math.max(max_x - min_x, max_y - min_y);
if (scale == 0) if (scale == 0) scale = 1;
scale = 1; else scale = 800 / scale; // svg view is 1000*1000
else
scale = 800/scale; // svg view is 1000*1000
this.posScale = scale; this.posScale = scale;
this.posTrans = { this.posTrans = {
x: - min_x * this.posScale + 100, x: -min_x * this.posScale + 100,
y: max_y * this.posScale + 100 y: max_y * this.posScale + 100,
}; };
} }
transform(x,y,theta,label, highlight) transform(x, y, theta, label, highlight) {
{
return [ return [
x * this.posScale + this.posTrans.x, x * this.posScale + this.posTrans.x,
- y * this.posScale + this.posTrans.y, -y * this.posScale + this.posTrans.y,
x, x,
y, y,
theta , theta,
label, label,
highlight highlight,
]; ];
} }
drawOneTrace(x, y, orgX, orgY, theta, label, highlight) drawOneTrace(x, y, orgX, orgY, theta, label, highlight) {
{
let svg = this.ui.querySelector("#svg-arrows"); let svg = this.ui.querySelector("#svg-arrows");
let g = document.createElementNS("http://www.w3.org/2000/svg", 'g'); let g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.innerHTML = `<title>${label}</title>`; g.innerHTML = `<title>${label}</title>`;
g.setAttribute("class","one-track"); g.setAttribute("class", "one-track");
g.ondblclick = (e)=>{ g.ondblclick = (e) => {
if (this.funcOnExit){ if (this.funcOnExit) {
this.hide(); this.hide();
this.funcOnExit(label); this.funcOnExit(label);
} }
}; };
if (highlight) if (highlight) {
{
g.setAttribute("class", "one-track object-track-current-frame"); g.setAttribute("class", "one-track object-track-current-frame");
} }
@ -245,16 +223,16 @@ class Trajectory extends PopupDialog{
let a = 5 * this.objScale; let a = 5 * this.objScale;
//wrapper circle //wrapper circle
let p = document.createElementNS("http://www.w3.org/2000/svg", 'circle'); let p = document.createElementNS("http://www.w3.org/2000/svg", "circle");
p.setAttribute("cx", x + (d-r)/2 * this.viewScale * Math.cos(theta)); p.setAttribute("cx", x + ((d - r) / 2) * this.viewScale * Math.cos(theta));
p.setAttribute("cy", y - (d-r)/2 * this.viewScale* Math.sin(theta)); p.setAttribute("cy", y - ((d - r) / 2) * this.viewScale * Math.sin(theta));
p.setAttribute("r", (d+2*r)/2 * this.viewScale); p.setAttribute("r", ((d + 2 * r) / 2) * this.viewScale);
p.setAttribute("class","track-wrapper"); p.setAttribute("class", "track-wrapper");
g.appendChild(p); g.appendChild(p);
//object //object
p = document.createElementNS("http://www.w3.org/2000/svg", 'circle'); p = document.createElementNS("http://www.w3.org/2000/svg", "circle");
p.setAttribute("cx", x); p.setAttribute("cx", x);
p.setAttribute("cy", y); p.setAttribute("cy", y);
p.setAttribute("r", r * this.viewScale); p.setAttribute("r", r * this.viewScale);
@ -278,14 +256,13 @@ class Trajectory extends PopupDialog{
// p.setAttribute("y2", y - d * this.viewScale * Math.sin(theta) + a * this.viewScale * Math.sin(-Math.PI/6+theta)); // p.setAttribute("y2", y - d * this.viewScale * Math.sin(theta) + a * this.viewScale * Math.sin(-Math.PI/6+theta));
// g.appendChild(p); // g.appendChild(p);
// direction // direction
p = document.createElementNS("http://www.w3.org/2000/svg", 'line'); p = document.createElementNS("http://www.w3.org/2000/svg", "line");
p.setAttribute("x1", x + r * this.viewScale * Math.cos(theta)); p.setAttribute("x1", x + r * this.viewScale * Math.cos(theta));
p.setAttribute("y1", y - r * this.viewScale* Math.sin(theta)); p.setAttribute("y1", y - r * this.viewScale * Math.sin(theta));
p.setAttribute("x2", x + d * this.viewScale * Math.cos(theta)); p.setAttribute("x2", x + d * this.viewScale * Math.cos(theta));
p.setAttribute("y2", y - d * this.viewScale* Math.sin(theta)); p.setAttribute("y2", y - d * this.viewScale * Math.sin(theta));
g.appendChild(p); g.appendChild(p);
// frame // frame
@ -295,34 +272,29 @@ class Trajectory extends PopupDialog{
// p.textContent = track[0]; // p.textContent = track[0];
// g.appendChild(p); // g.appendChild(p);
p = document.createElementNS("http://www.w3.org/2000/svg", 'foreignObject'); p = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
p.setAttribute("x", x + 50 * this.viewScale); p.setAttribute("x", x + 50 * this.viewScale);
p.setAttribute("y", y); p.setAttribute("y", y);
// p.setAttribute("width", 200 * this.scale); // p.setAttribute("width", 200 * this.scale);
p.setAttribute("font-size", 10 * this.viewScale+"px"); p.setAttribute("font-size", 10 * this.viewScale + "px");
p.setAttribute("class",'track-label'); p.setAttribute("class", "track-label");
let text = document.createElementNS("http://www.w3.org/1999/xhtml", 'div'); let text = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
text.textContent = label; text.textContent = label;
p.appendChild(text); p.appendChild(text);
g.appendChild(p); g.appendChild(p);
} }
calculateScalerUnit() calculateScalerUnit() {
{ let x = 100 / this.posScale;
let x = 100/this.posScale;
let e = 0; let e = 0;
while (x >= 10 || x < 1) while (x >= 10 || x < 1) {
{ if (x >= 10) {
if (x >= 10)
{
e += 1; e += 1;
x /= 10; x /= 10;
} } else if (x < 1) {
else if (x < 1)
{
e -= 1; e -= 1;
x *= 10; x *= 10;
} }
@ -333,89 +305,84 @@ class Trajectory extends PopupDialog{
return x; return x;
} }
drawScaler() drawScaler() {
{
let x = this.calculateScalerUnit(); let x = this.calculateScalerUnit();
let lineLen = x * this.posScale; let lineLen = x * this.posScale;
let svg = this.ui.querySelector("#svg-scaler"); let svg = this.ui.querySelector("#svg-scaler");
let g = document.createElementNS("http://www.w3.org/2000/svg", 'g'); let g = document.createElementNS("http://www.w3.org/2000/svg", "g");
svg.appendChild(g); svg.appendChild(g);
//direction //direction
let p = document.createElementNS("http://www.w3.org/2000/svg", 'line'); let p = document.createElementNS("http://www.w3.org/2000/svg", "line");
p.setAttribute("x1", 100); p.setAttribute("x1", 100);
p.setAttribute("y1", 900); p.setAttribute("y1", 900);
p.setAttribute("x2", 100+lineLen); p.setAttribute("x2", 100 + lineLen);
p.setAttribute("y2", 900); p.setAttribute("y2", 900);
g.appendChild(p); g.appendChild(p);
p = document.createElementNS("http://www.w3.org/2000/svg", 'line'); p = document.createElementNS("http://www.w3.org/2000/svg", "line");
p.setAttribute("x1", 100); p.setAttribute("x1", 100);
p.setAttribute("y1", 900); p.setAttribute("y1", 900);
p.setAttribute("x2", 100); p.setAttribute("x2", 100);
p.setAttribute("y2", 900-lineLen); p.setAttribute("y2", 900 - lineLen);
g.appendChild(p); g.appendChild(p);
p = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
p = document.createElementNS("http://www.w3.org/2000/svg", 'foreignObject');
p.setAttribute("x", 105); p.setAttribute("x", 105);
p.setAttribute("y", 875); p.setAttribute("y", 875);
// p.setAttribute("width", 200 * this.scale); // p.setAttribute("width", 200 * this.scale);
p.setAttribute("font-size", 10 * this.viewScale+"px"); p.setAttribute("font-size", 10 * this.viewScale + "px");
p.setAttribute("class",'scaler-label'); p.setAttribute("class", "scaler-label");
let text = document.createElementNS("http://www.w3.org/1999/xhtml", 'div'); let text = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
text.textContent = x.toString() + 'm'; text.textContent = x.toString() + "m";
p.appendChild(text); p.appendChild(text);
g.appendChild(p); g.appendChild(p);
} }
drawTracks(object) {
drawTracks(object) this.titleUi.innerText = object.type + " " + +object.id;
{
this.titleUi.innerText = object.type + " "+ + object.id;
let tracks = object.tracks; let tracks = object.tracks;
tracks
tracks.filter(x=>x[1]) .filter((x) => x[1])
.map(track=>[track[1].psr.position.x, track[1].psr.position.y, track[1].psr.rotation.z, track[0], track[2]]) .map((track) => [
.map(x=>this.transform(...x)) track[1].psr.position.x,
.forEach(x=>this.drawOneTrace(...x)); track[1].psr.position.y,
track[1].psr.rotation.z,
track[0],
track[2],
])
.map((x) => this.transform(...x))
.forEach((x) => this.drawOneTrace(...x));
//ego car //ego car
//this.draw_ego_car(...this.transform(0,0,0,"",false).slice(0,2)); //this.draw_ego_car(...this.transform(0,0,0,"",false).slice(0,2));
} }
draw_ego_car(x, y) {
draw_ego_car(x,y)
{
let svg = this.ui.querySelector("#svg-arrows"); let svg = this.ui.querySelector("#svg-arrows");
let g = document.createElementNS("http://www.w3.org/2000/svg", 'g'); let g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.innerHTML = `<title>Ego car</title>`; g.innerHTML = `<title>Ego car</title>`;
g.setAttribute("id", "track-ego-car"); g.setAttribute("id", "track-ego-car");
svg.appendChild(g); svg.appendChild(g);
let p = document.createElementNS("http://www.w3.org/2000/svg", 'line'); let p = document.createElementNS("http://www.w3.org/2000/svg", "line");
p.setAttribute("x1", x-10 * this.viewScale); p.setAttribute("x1", x - 10 * this.viewScale);
p.setAttribute("y1", y); p.setAttribute("y1", y);
p.setAttribute("x2", x+10 * this.viewScale); p.setAttribute("x2", x + 10 * this.viewScale);
p.setAttribute("y2", y); p.setAttribute("y2", y);
g.appendChild(p); g.appendChild(p);
p = document.createElementNS("http://www.w3.org/2000/svg", 'line'); p = document.createElementNS("http://www.w3.org/2000/svg", "line");
p.setAttribute("x1", x); p.setAttribute("x1", x);
p.setAttribute("y1", y-10 * this.viewScale); p.setAttribute("y1", y - 10 * this.viewScale);
p.setAttribute("x2", x); p.setAttribute("x2", x);
p.setAttribute("y2", y+10 * this.viewScale); p.setAttribute("y2", y + 10 * this.viewScale);
g.appendChild(p); g.appendChild(p);
} }
} }
export { Trajectory };
export {Trajectory};

@ -1,29 +1,29 @@
import * as THREE from './lib/three.module.js'; import * as THREE from "./lib/three.module.js";
function dotproduct(a, b){ function dotproduct(a, b) {
var ret = 0; var ret = 0;
for (let i = 0; i<a.length; i++){ for (let i = 0; i < a.length; i++) {
ret += a[i]*b[i]; ret += a[i] * b[i];
} }
return ret; return ret;
} }
// matrix (m*n), matrix(n*l), vl: vector length=n // matrix (m*n), matrix(n*l), vl: vector length=n
// this matmul is row-wise multiplication. 'x' and result are row-vectors. // this matmul is row-wise multiplication. 'x' and result are row-vectors.
// ret^T = m * x^T // ret^T = m * x^T
// //
function matmul(m, x, vl) //vl is vector length function matmul(m, x, vl) {
{ //vl is vector length
var ret=[]; var ret = [];
var res_l = m.length/vl; var res_l = m.length / vl;
for (var vi =0; vi < x.length/vl; vi++){ //vector index for (var vi = 0; vi < x.length / vl; vi++) {
for (var r = 0; r<m.length/vl; r++){ //row of matrix //vector index
ret[vi*res_l+r] = 0; for (var r = 0; r < m.length / vl; r++) {
for (var i = 0; i<vl; i++){ //row of matrix
ret[vi*res_l+r] += m[r*vl+i]*x[vi*vl+i]; ret[vi * res_l + r] = 0;
for (var i = 0; i < vl; i++) {
ret[vi * res_l + r] += m[r * vl + i] * x[vi * vl + i];
} }
} }
} }
@ -31,16 +31,16 @@ function matmul(m, x, vl) //vl is vector length
return ret; return ret;
} }
function matmul2(m, x, vl) //vl is vector length function matmul2(m, x, vl) {
{ //vl is vector length
var ret=[]; var ret = [];
var rows = m.length/vl; var rows = m.length / vl;
var cols = x.length/vl; var cols = x.length / vl;
for (var r =0; r < rows; r++){ for (var r = 0; r < rows; r++) {
for (var c = 0; c < cols; c++){ for (var c = 0; c < cols; c++) {
ret[r*cols+c] = 0; ret[r * cols + c] = 0;
for (var i = 0; i<vl; i++){ for (var i = 0; i < vl; i++) {
ret[r*cols+c] += m[r*vl+i]*x[i*cols+c]; ret[r * cols + c] += m[r * vl + i] * x[i * cols + c];
} }
} }
} }
@ -52,7 +52,7 @@ function matmul2(m, x, vl) //vl is vector length
// return 8 points, represented as (x,y,z,1) // return 8 points, represented as (x,y,z,1)
// note the vertices order cannot be changed, draw-box-on-image assumes // note the vertices order cannot be changed, draw-box-on-image assumes
// the first 4 vertex is the front plane, so it knows box direction. // the first 4 vertex is the front plane, so it knows box direction.
function psr_to_xyz(p,s,r){ function psr_to_xyz(p, s, r) {
/* /*
var trans_matrix=[ var trans_matrix=[
Math.cos(r.z), -Math.sin(r.z), 0, p.x, Math.cos(r.z), -Math.sin(r.z), 0, p.x,
@ -63,9 +63,9 @@ function psr_to_xyz(p,s,r){
*/ */
var trans_matrix = euler_angle_to_rotate_matrix(r, p); var trans_matrix = euler_angle_to_rotate_matrix(r, p);
var x=s.x/2; var x = s.x / 2;
var y=s.y/2; var y = s.y / 2;
var z=s.z/2; var z = s.z / 2;
/* /*
var local_coord = [ var local_coord = [
-x, y, -z, 1, x, y, -z, 1, //front-left-bottom, front-right-bottom -x, y, -z, 1, x, y, -z, 1, //front-left-bottom, front-right-bottom
@ -78,11 +78,39 @@ function psr_to_xyz(p,s,r){
*/ */
var local_coord = [ var local_coord = [
x, y, -z, 1, x, -y, -z, 1, //front-left-bottom, front-right-bottom x,
x, -y, z, 1, x, y, z, 1, //front-right-top, front-left-top y,
-z,
-x, y, -z, 1, -x, -y, -z, 1, //rear-left-bottom, rear-right-bottom 1,
-x, -y, z, 1, -x, y, z, 1, //rear-right-top, rear-left-top x,
-y,
-z,
1, //front-left-bottom, front-right-bottom
x,
-y,
z,
1,
x,
y,
z,
1, //front-right-top, front-left-top
-x,
y,
-z,
1,
-x,
-y,
-z,
1, //rear-left-bottom, rear-right-bottom
-x,
-y,
z,
1,
-x,
y,
z,
1, //rear-right-top, rear-left-top
//middle plane //middle plane
// 0, y, -z, 1, 0, -y, -z, 1, //rear-left-bottom, rear-right-bottom // 0, y, -z, 1, 0, -y, -z, 1, //rear-left-bottom, rear-right-bottom
@ -94,27 +122,29 @@ function psr_to_xyz(p,s,r){
return w; return w;
} }
function xyz_to_psr(vertices) {
function xyz_to_psr(vertices){
var ann = vertices; var ann = vertices;
var ROW=4; var ROW = 4;
var pos={x:0,y:0,z:0}; var pos = { x: 0, y: 0, z: 0 };
for (var i=0; i<8; i++){ for (var i = 0; i < 8; i++) {
pos.x+=ann[i*ROW]; pos.x += ann[i * ROW];
pos.y+=ann[i*ROW+1]; pos.y += ann[i * ROW + 1];
pos.z+=ann[i*ROW+2]; pos.z += ann[i * ROW + 2];
} }
pos.x /=8; pos.x /= 8;
pos.y /=8; pos.y /= 8;
pos.z /=8; pos.z /= 8;
var scale = {
x: Math.sqrt(
var scale={ (ann[0] - ann[ROW]) * (ann[0] - ann[ROW]) +
x: Math.sqrt((ann[0]-ann[ROW])*(ann[0]-ann[ROW])+(ann[1]-ann[ROW+1])*(ann[1]-ann[ROW+1])), (ann[1] - ann[ROW + 1]) * (ann[1] - ann[ROW + 1])
y: Math.sqrt((ann[0]-ann[ROW*3])*(ann[0]-ann[ROW*3])+(ann[1]-ann[ROW*3+1])*(ann[1]-ann[ROW*3+1])), ),
z: ann[3*ROW+2]-ann[2], y: Math.sqrt(
(ann[0] - ann[ROW * 3]) * (ann[0] - ann[ROW * 3]) +
(ann[1] - ann[ROW * 3 + 1]) * (ann[1] - ann[ROW * 3 + 1])
),
z: ann[3 * ROW + 2] - ann[2],
}; };
/* /*
@ -124,22 +154,23 @@ function xyz_to_psr(vertices){
3 2 3 2
*/ */
var angle = Math.atan2(ann[1*ROW+1]+ann[5*ROW+1]-2*pos.y, ann[1*ROW]+ann[5*ROW]-2*pos.x); var angle = Math.atan2(
ann[1 * ROW + 1] + ann[5 * ROW + 1] - 2 * pos.y,
ann[1 * ROW] + ann[5 * ROW] - 2 * pos.x
);
return { return {
position: pos, position: pos,
scale:scale, scale: scale,
rotation:{x:0,y:0,z:angle}, rotation: { x: 0, y: 0, z: angle },
} };
return w; return w;
} }
function vector4to3(v) {
function vector4to3(v) var ret = [];
{ for (var i = 0; i < v.length; i++) {
var ret=[]; if ((i + 1) % 4 != 0) {
for (var i=0; i<v.length; i++){
if ((i+1)% 4 != 0){
ret.push(v[i]); ret.push(v[i]);
} }
} }
@ -147,9 +178,8 @@ function vector4to3(v)
return ret; return ret;
} }
function vector_range(v){ function vector_range(v) {
if (v.length === 0) {
if (v.length === 0){
return null; return null;
} }
@ -157,13 +187,13 @@ function vector_range(v){
min = [...v[0]]; min = [...v[0]];
max = [...v[0]]; max = [...v[0]];
for (var i=1; i<v.length; ++i){ for (var i = 1; i < v.length; ++i) {
for (var j=0; j<min.length; ++j){ for (var j = 0; j < min.length; ++j) {
if (min[j] > v[i][j]){ if (min[j] > v[i][j]) {
min[j] = v[i][j]; min[j] = v[i][j];
} }
if (max[j] < v[i][j]){ if (max[j] < v[i][j]) {
max[j] = v[i][j]; max[j] = v[i][j];
} }
} }
@ -172,31 +202,29 @@ function vector_range(v){
return { return {
min: min, min: min,
max: max, max: max,
} };
} }
// v is array of vector, vl is vector length // v is array of vector, vl is vector length
function array_as_vector_range(v, vl){ function array_as_vector_range(v, vl) {
var n = v.length / vl;
var n = v.length/vl;
var min, max; var min, max;
if (n === 0){ if (n === 0) {
return null; return null;
} else{ } else {
min = v.slice(0, vl); min = v.slice(0, vl);
max = v.slice(0, vl); max = v.slice(0, vl);
} }
for (var i=1; i<n; ++i){ for (var i = 1; i < n; ++i) {
for (var j=0; j<vl; ++j){ for (var j = 0; j < vl; ++j) {
if (min[j] > v[i*vl+j]){ if (min[j] > v[i * vl + j]) {
min[j] = v[i*vl+j]; min[j] = v[i * vl + j];
} }
if (max[j] < v[i*vl+j]){ if (max[j] < v[i * vl + j]) {
max[j] = v[i*vl+j]; max[j] = v[i * vl + j];
} }
} }
} }
@ -204,30 +232,29 @@ function array_as_vector_range(v, vl){
return { return {
min: min, min: min,
max: max, max: max,
} };
} }
// v is 1-d array of vector, vl is vector length, p is index into v. // v is 1-d array of vector, vl is vector length, p is index into v.
function array_as_vector_index_range(v, vl, p){ function array_as_vector_index_range(v, vl, p) {
var n = p.length; var n = p.length;
var min, max; var min, max;
if (n === 0){ if (n === 0) {
return null; return null;
} else{ } else {
min = v.slice(p[0]*vl, (p[0]+1)*vl); min = v.slice(p[0] * vl, (p[0] + 1) * vl);
max = v.slice(p[0]*vl, (p[0]+1)*vl); max = v.slice(p[0] * vl, (p[0] + 1) * vl);
} }
for (var i=1; i<n; ++i){ for (var i = 1; i < n; ++i) {
for (var j=0; j<vl; ++j){ for (var j = 0; j < vl; ++j) {
if (min[j] > v[p[i]*vl+j]){ if (min[j] > v[p[i] * vl + j]) {
min[j] = v[p[i]*vl+j]; min[j] = v[p[i] * vl + j];
} }
if (max[j] < v[p[i]*vl+j]){ if (max[j] < v[p[i] * vl + j]) {
max[j] = v[p[i]*vl+j]; max[j] = v[p[i] * vl + j];
} }
} }
} }
@ -235,63 +262,77 @@ function array_as_vector_index_range(v, vl, p){
return { return {
min: min, min: min,
max: max, max: max,
} };
} }
function vector3_nomalize(m) {
var ret = [];
function vector3_nomalize(m){ for (var i = 0; i < m.length / 3; i++) {
var ret=[]; ret.push(m[i * 3 + 0] / m[i * 3 + 2]);
for (var i=0; i<m.length/3; i++){ ret.push(m[i * 3 + 1] / m[i * 3 + 2]);
ret.push(m[i*3+0]/m[i*3+2]);
ret.push(m[i*3+1]/m[i*3+2]);
} }
return ret; return ret;
} }
function mat(m, s, x, y) {
return m[x * s + y];
function mat(m, s, x, y){
return m[x*s+y];
} }
// m; matrix, vl: column vector length // m; matrix, vl: column vector length
function transpose(m, cl=NaN){ function transpose(m, cl = NaN) {
var rl = m.length/cl; var rl = m.length / cl;
for (var i = 0; i<cl; i++){ for (var i = 0; i < cl; i++) {
for(var j=i+1; j<rl; j++){ for (var j = i + 1; j < rl; j++) {
var t = m[i*rl + j]; var t = m[i * rl + j];
m[i*rl + j] = m[j*cl+i]; m[i * rl + j] = m[j * cl + i];
m[j*cl+i] = t; m[j * cl + i] = t;
} }
} }
return m; return m;
} }
function euler_angle_to_rotate_matrix(eu, tr, order="ZYX"){ function euler_angle_to_rotate_matrix(eu, tr, order = "ZYX") {
var theta = [eu.x, eu.y, eu.z]; var theta = [eu.x, eu.y, eu.z];
// Calculate rotation about x axis // Calculate rotation about x axis
var R_x = [ var R_x = [
1, 0, 0, 1,
0, Math.cos(theta[0]), -Math.sin(theta[0]), 0,
0, Math.sin(theta[0]), Math.cos(theta[0]) 0,
0,
Math.cos(theta[0]),
-Math.sin(theta[0]),
0,
Math.sin(theta[0]),
Math.cos(theta[0]),
]; ];
// Calculate rotation about y axis // Calculate rotation about y axis
var R_y = [ var R_y = [
Math.cos(theta[1]), 0, Math.sin(theta[1]), Math.cos(theta[1]),
0, 1, 0, 0,
-Math.sin(theta[1]), 0, Math.cos(theta[1]) Math.sin(theta[1]),
0,
1,
0,
-Math.sin(theta[1]),
0,
Math.cos(theta[1]),
]; ];
// Calculate rotation about z axis // Calculate rotation about z axis
var R_z = [ var R_z = [
Math.cos(theta[2]), -Math.sin(theta[2]), 0, Math.cos(theta[2]),
Math.sin(theta[2]), Math.cos(theta[2]), 0, -Math.sin(theta[2]),
0, 0, 1]; 0,
Math.sin(theta[2]),
Math.cos(theta[2]),
0,
0,
0,
1,
];
//console.log(R_x, R_y, R_z); //console.log(R_x, R_y, R_z);
@ -303,42 +344,74 @@ function euler_angle_to_rotate_matrix(eu, tr, order="ZYX"){
Z: R_z, Z: R_z,
Y: R_y, Y: R_y,
X: R_x, X: R_x,
} };
let R = matmul2(matrices[order[2]], matmul2(matrices[order[1]], matrices[order[0]], 3), 3);
let R = matmul2(
matrices[order[2]],
matmul2(matrices[order[1]], matrices[order[0]], 3),
3
);
return [ return [
mat(R,3,0,0), mat(R,3,0,1), mat(R,3,0,2), tr.x, mat(R, 3, 0, 0),
mat(R,3,1,0), mat(R,3,1,1), mat(R,3,1,2), tr.y, mat(R, 3, 0, 1),
mat(R,3,2,0), mat(R,3,2,1), mat(R,3,2,2), tr.z, mat(R, 3, 0, 2),
0, 0, 0, 1, tr.x,
mat(R, 3, 1, 0),
mat(R, 3, 1, 1),
mat(R, 3, 1, 2),
tr.y,
mat(R, 3, 2, 0),
mat(R, 3, 2, 1),
mat(R, 3, 2, 2),
tr.z,
0,
0,
0,
1,
]; ];
} }
function euler_angle_to_rotate_matrix_3by3(eu, order = "ZYX") {
function euler_angle_to_rotate_matrix_3by3(eu, order="ZYX"){
var theta = [eu.x, eu.y, eu.z]; var theta = [eu.x, eu.y, eu.z];
// Calculate rotation about x axis // Calculate rotation about x axis
var R_x = [ var R_x = [
1, 0, 0, 1,
0, Math.cos(theta[0]), -Math.sin(theta[0]), 0,
0, Math.sin(theta[0]), Math.cos(theta[0]) 0,
0,
Math.cos(theta[0]),
-Math.sin(theta[0]),
0,
Math.sin(theta[0]),
Math.cos(theta[0]),
]; ];
// Calculate rotation about y axis // Calculate rotation about y axis
var R_y = [ var R_y = [
Math.cos(theta[1]), 0, Math.sin(theta[1]), Math.cos(theta[1]),
0, 1, 0, 0,
-Math.sin(theta[1]), 0, Math.cos(theta[1]) Math.sin(theta[1]),
0,
1,
0,
-Math.sin(theta[1]),
0,
Math.cos(theta[1]),
]; ];
// Calculate rotation about z axis // Calculate rotation about z axis
var R_z = [ var R_z = [
Math.cos(theta[2]), -Math.sin(theta[2]), 0, Math.cos(theta[2]),
Math.sin(theta[2]), Math.cos(theta[2]), 0, -Math.sin(theta[2]),
0, 0, 1]; 0,
Math.sin(theta[2]),
Math.cos(theta[2]),
0,
0,
0,
1,
];
//console.log(R_x, R_y, R_z); //console.log(R_x, R_y, R_z);
@ -349,18 +422,29 @@ function euler_angle_to_rotate_matrix_3by3(eu, order="ZYX"){
Z: R_z, Z: R_z,
Y: R_y, Y: R_y,
X: R_x, X: R_x,
} };
let R = matmul2(matrices[order[2]], matmul2(matrices[order[1]], matrices[order[0]], 3), 3); let R = matmul2(
matrices[order[2]],
matmul2(matrices[order[1]], matrices[order[0]], 3),
3
);
return [ return [
mat(R,3,0,0), mat(R,3,0,1), mat(R,3,0,2), mat(R, 3, 0, 0),
mat(R,3,1,0), mat(R,3,1,1), mat(R,3,1,2), mat(R, 3, 0, 1),
mat(R,3,2,0), mat(R,3,2,1), mat(R,3,2,2), mat(R, 3, 0, 2),
mat(R, 3, 1, 0),
mat(R, 3, 1, 1),
mat(R, 3, 1, 2),
mat(R, 3, 2, 0),
mat(R, 3, 2, 1),
mat(R, 3, 2, 2),
]; ];
} }
function rotation_matrix_to_euler_angle(m, msize){ //m is 4* 4 function rotation_matrix_to_euler_angle(m, msize) {
//m is 4* 4
/* /*
@ -379,78 +463,122 @@ function rotation_matrix_to_euler_angle(m, msize){ //m is 4* 4
}; };
*/ */
var odd = false; var odd = false;
var res = [0,0,0]; var res = [0, 0, 0];
var i=0,j=1,k=2; var i = 0,
j = 1,
k = 2;
if (!msize){ if (!msize) {
msize=4 msize = 4;
} }
function coeff(x,y){return mat(m,msize,x,y); } function coeff(x, y) {
return mat(m, msize, x, y);
}
function atan2(x,y) { return Math.atan2(x,y);} function atan2(x, y) {
return Math.atan2(x, y);
}
var sin = Math.sin; var sin = Math.sin;
var cos = Math.cos; var cos = Math.cos;
function Scalar(x){return x;} function Scalar(x) {
return x;
}
res[0] = atan2(coeff(j,k), coeff(k,k)); res[0] = atan2(coeff(j, k), coeff(k, k));
//var c2 = Vector2(coeff(i,i), coeff(i,j)).norm(); //var c2 = Vector2(coeff(i,i), coeff(i,j)).norm();
var c2 = Math.sqrt(coeff(i,i)*coeff(i,i) + coeff(i,j)*coeff(i,j)); var c2 = Math.sqrt(coeff(i, i) * coeff(i, i) + coeff(i, j) * coeff(i, j));
if((odd && res[0]<Scalar(0)) || ((!odd) && res[0]>Scalar(0))) { if ((odd && res[0] < Scalar(0)) || (!odd && res[0] > Scalar(0))) {
if(res[0] > Scalar(0)) { if (res[0] > Scalar(0)) {
res[0] -= Scalar(Math.PI); res[0] -= Scalar(Math.PI);
} } else {
else {
res[0] += Scalar(Math.PI); res[0] += Scalar(Math.PI);
} }
res[1] = atan2(-coeff(i,k), -c2); res[1] = atan2(-coeff(i, k), -c2);
} } else res[1] = atan2(-coeff(i, k), c2);
else
res[1] = atan2(-coeff(i,k), c2);
var s1 = sin(res[0]); var s1 = sin(res[0]);
var c1 = cos(res[0]); var c1 = cos(res[0]);
res[2] = atan2(s1*coeff(k,i)-c1*coeff(j,i), c1*coeff(j,j) - s1 * coeff(k,j)); res[2] = atan2(
s1 * coeff(k, i) - c1 * coeff(j, i),
c1 * coeff(j, j) - s1 * coeff(k, j)
);
if (!odd) if (!odd)
res = res.map(function(x){return -x;}) res = res.map(function (x) {
return -x;
});
return { return {
x: res[0], x: res[0],
y: res[1], y: res[1],
z: res[2], z: res[2],
} };
} }
var linalg_std = { var linalg_std = {
euler_angle_to_rotation_matrix: function(euler){ euler_angle_to_rotation_matrix: function (euler) {
var theta = [euler.x, euler.y, euler.z]; var theta = [euler.x, euler.y, euler.z];
// Calculate rotation about x axis // Calculate rotation about x axis
var R_x = new THREE.Matrix4(); var R_x = new THREE.Matrix4();
R_x.set( R_x.set(
1, 0, 0, 0, 1,
0, Math.cos(theta[0]), -Math.sin(theta[0]), 0, 0,
0, Math.sin(theta[0]), Math.cos(theta[0]) , 0, 0,
0, 0, 0, 1, 0,
0,
Math.cos(theta[0]),
-Math.sin(theta[0]),
0,
0,
Math.sin(theta[0]),
Math.cos(theta[0]),
0,
0,
0,
0,
1
); );
// Calculate rotation about y axis // Calculate rotation about y axis
var R_y = new THREE.Matrix4(); var R_y = new THREE.Matrix4();
R_y.set( R_y.set(
Math.cos(theta[1]), 0, Math.sin(theta[1]), 0, Math.cos(theta[1]),
0, 1, 0, 0, 0,
-Math.sin(theta[1]), 0, Math.cos(theta[1]), 0, Math.sin(theta[1]),
0, 0, 0, 1, 0,
0,
1,
0,
0,
-Math.sin(theta[1]),
0,
Math.cos(theta[1]),
0,
0,
0,
0,
1
); );
// Calculate rotation about z axis // Calculate rotation about z axis
var R_z = new THREE.Matrix4(); var R_z = new THREE.Matrix4();
R_z.set( R_z.set(
Math.cos(theta[2]), -Math.sin(theta[2]), 0, 0, Math.cos(theta[2]),
Math.sin(theta[2]), Math.cos(theta[2]), 0, 0, -Math.sin(theta[2]),
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
Math.sin(theta[2]),
Math.cos(theta[2]),
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
); );
R_z.multiply(R_y); R_z.multiply(R_y);
@ -459,44 +587,36 @@ var linalg_std = {
return R_z; return R_z;
}, },
euler_angle_from_rotation_matrix: function(m){ euler_angle_from_rotation_matrix: function (m) {
var euler = new THREE.Euler(); var euler = new THREE.Euler();
euler.setFromRotationMatrix(m); euler.setFromRotationMatrix(m);
return euler; return euler;
}, },
// {x:, y:, z:} // {x:, y:, z:}
euler_angle_composite: function(current, delta){ euler_angle_composite: function (current, delta) {
var current_matrix = this.euler_angle_to_rotation_matrix(current); var current_matrix = this.euler_angle_to_rotation_matrix(current);
var delta_matrix = this.euler_angle_to_rotation_matrix(delta); var delta_matrix = this.euler_angle_to_rotation_matrix(delta);
var composite_matrix = new THREE.Matrix4(); var composite_matrix = new THREE.Matrix4();
composite_matrix.multiplyMatrices(delta_matrix, current_matrix); composite_matrix.multiplyMatrices(delta_matrix, current_matrix);
return this.euler_angle_from_rotation_matrix(composite_matrix); return this.euler_angle_from_rotation_matrix(composite_matrix);
} },
} };
function normalizeAngle(a) function normalizeAngle(a) {
{ while (true) {
while (true) if (a > Math.PI) a -= Math.PI * 2;
{ else if (a < -Math.PI) a += Math.PI * 2;
if ( a > Math.PI) else return a;
a -= Math.PI *2;
else if (a < -Math.PI)
a += Math.PI * 2;
else
return a;
} }
} }
// box(position, scale, rotation) to box corner corrdinates. // box(position, scale, rotation) to box corner corrdinates.
// return 8 points, represented as (x,y,z,1) // return 8 points, represented as (x,y,z,1)
// note the vertices order cannot be changed, draw-box-on-image assumes // note the vertices order cannot be changed, draw-box-on-image assumes
// the first 4 vertex is the front plane, so it knows box direction. // the first 4 vertex is the front plane, so it knows box direction.
function psr_to_xyz_face_points(p,s,r, minGrid){ function psr_to_xyz_face_points(p, s, r, minGrid) {
/* /*
var trans_matrix=[ var trans_matrix=[
Math.cos(r.z), -Math.sin(r.z), 0, p.x, Math.cos(r.z), -Math.sin(r.z), 0, p.x,
@ -507,129 +627,128 @@ function psr_to_xyz_face_points(p,s,r, minGrid){
*/ */
var trans_matrix = euler_angle_to_rotate_matrix(r, p); var trans_matrix = euler_angle_to_rotate_matrix(r, p);
var x=s.x/2; var x = s.x / 2;
var y=s.y/2; var y = s.y / 2;
var z=s.z/2; var z = s.z / 2;
// var local_coord = [
// [x, y, -z], [x, -y, -z], //front-left-bottom, front-right-bottom
// [x, -y, z], [x, y, z], //front-right-top, front-left-top
// [-x, y, -z], [-x, -y, -z], //rear-left-bottom, rear-right-bottom
// [-x, -y, z], [-x, y, z], //rear-right-top, rear-left-top
// ];
// var local_coord = [
// [x, y, -z], [x, -y, -z], //front-left-bottom, front-right-bottom
// [x, -y, z], [x, y, z], //front-right-top, front-left-top
// [-x, y, -z], [-x, -y, -z], //rear-left-bottom, rear-right-bottom
// [-x, -y, z], [-x, y, z], //rear-right-top, rear-left-top
// ];
let xs = []; let xs = [];
for (let i = -x ; i <=x; i+=minGrid) for (let i = -x; i <= x; i += minGrid) {
{
xs.push(i); xs.push(i);
} }
let ys = []; let ys = [];
for (let i = -y ; i <=y; i+=minGrid) for (let i = -y; i <= y; i += minGrid) {
{
ys.push(i); ys.push(i);
} }
let zs = []; let zs = [];
for (let i = -z ; i <=z; i+=minGrid) for (let i = -z; i <= z; i += minGrid) {
{
zs.push(i); zs.push(i);
} }
let points = []; let points = [];
points = points.concat(ys.map(i=>[x, i, -z, 1])); points = points.concat(ys.map((i) => [x, i, -z, 1]));
points = points.concat(ys.map(i=>[x, i, z, 1])); points = points.concat(ys.map((i) => [x, i, z, 1]));
points = points.concat(ys.map(i=>[-x, i, -z, 1])); points = points.concat(ys.map((i) => [-x, i, -z, 1]));
points = points.concat(ys.map(i=>[-x, i, z, 1])); points = points.concat(ys.map((i) => [-x, i, z, 1]));
points = points.concat(xs.map(i=>[i, y, -z, 1])); points = points.concat(xs.map((i) => [i, y, -z, 1]));
points = points.concat(xs.map(i=>[i, y, z, 1])); points = points.concat(xs.map((i) => [i, y, z, 1]));
points = points.concat(xs.map(i=>[i, -y, -z, 1])); points = points.concat(xs.map((i) => [i, -y, -z, 1]));
points = points.concat(xs.map(i=>[i, -y, z, 1])); points = points.concat(xs.map((i) => [i, -y, z, 1]));
points = points.concat(zs.map(i=>[x, y, i, 1])); points = points.concat(zs.map((i) => [x, y, i, 1]));
points = points.concat(zs.map(i=>[x, -y, i, 1])); points = points.concat(zs.map((i) => [x, -y, i, 1]));
points = points.concat(zs.map(i=>[-x, -y, i, 1])); points = points.concat(zs.map((i) => [-x, -y, i, 1]));
points = points.concat(zs.map(i=>[-x, y, i, 1])); points = points.concat(zs.map((i) => [-x, y, i, 1]));
points = points.reduce((a, b) => a.concat(b));
points = points.reduce((a,b)=>a.concat(b))
let world_coord = matmul(trans_matrix, points, 4); let world_coord = matmul(trans_matrix, points, 4);
return vector4to3(world_coord); return vector4to3(world_coord);
} }
function cornersAinB(boxA, boxB) {
function cornersAinB(boxA,boxB){
let minGrid = Math.min( let minGrid = Math.min(
boxA.scale.x, boxA.scale.y, boxA.scale.z, boxA.scale.x,
boxB.scale.x, boxB.scale.y, boxB.scale.z, boxA.scale.y,
boxA.scale.z,
boxB.scale.x,
boxB.scale.y,
boxB.scale.z
); );
minGrid = minGrid / 2; minGrid = minGrid / 2;
// in world coord, offset by b pos // in world coord, offset by b pos
let boxAPosInB = {x: boxA.position.x - boxB.position.x, let boxAPosInB = {
x: boxA.position.x - boxB.position.x,
y: boxA.position.y - boxB.position.y, y: boxA.position.y - boxB.position.y,
z: boxA.position.z - boxB.position.z}; z: boxA.position.z - boxB.position.z,
};
let cornersA = psr_to_xyz_face_points(boxAPosInB, boxA.scale, boxA.rotation, minGrid); // in world coordinates let cornersA = psr_to_xyz_face_points(
boxAPosInB,
boxA.scale,
boxA.rotation,
minGrid
); // in world coordinates
cornersA.push(boxAPosInB.x, boxAPosInB.y, boxAPosInB.z); //center point cornersA.push(boxAPosInB.x, boxAPosInB.y, boxAPosInB.z); //center point
// in box b coord // in box b coord
let matrixB = euler_angle_to_rotate_matrix_3by3(boxB.rotation); let matrixB = euler_angle_to_rotate_matrix_3by3(boxB.rotation);
matrixB = transpose(matrixB,3) matrixB = transpose(matrixB, 3);
let cornersAInB = matmul(matrixB, cornersA, 3); let cornersAInB = matmul(matrixB, cornersA, 3);
for (let i = 0; i < cornersAInB.length; i += 3) {
let [x, y, z] = cornersAInB.slice(i, i + 3);
for (let i =0; i < cornersAInB.length; i+=3){ if (
let [x,y,z] = cornersAInB.slice(i, i+3) Math.abs(x) < boxB.scale.x / 2 &&
Math.abs(y) < boxB.scale.y / 2 &&
if ( Math.abs(x) < boxB.scale.x/2 && Math.abs(z) < boxB.scale.z / 2
Math.abs(y) < boxB.scale.y/2 && ) {
Math.abs(z) < boxB.scale.z/2)
{
return true; return true;
} }
} }
return false; return false;
} }
// check if 2 boxes has non-empty intersection // check if 2 boxes has non-empty intersection
// the idea is to check if any corner of one box is inside the other one // the idea is to check if any corner of one box is inside the other one
// when boxA contains B entirely, we shoudl test the opposite way. // when boxA contains B entirely, we shoudl test the opposite way.
function intersect(boxA, boxB){ function intersect(boxA, boxB) {
return cornersAinB(boxA, boxB) || cornersAinB(boxB, boxA); return cornersAinB(boxA, boxB) || cornersAinB(boxB, boxA);
}
export {
dotproduct,
}; vector_range,
array_as_vector_range,
array_as_vector_index_range,
export {dotproduct, vector_range, array_as_vector_range, array_as_vector_index_range, vector4to3, vector3_nomalize, psr_to_xyz, matmul, vector4to3,
vector3_nomalize,
psr_to_xyz,
matmul,
matmul2, matmul2,
euler_angle_to_rotate_matrix_3by3, euler_angle_to_rotate_matrix, rotation_matrix_to_euler_angle, euler_angle_to_rotate_matrix_3by3,
euler_angle_to_rotate_matrix,
rotation_matrix_to_euler_angle,
linalg_std, linalg_std,
transpose, transpose,
mat, mat,
normalizeAngle, normalizeAngle,
intersect intersect,
} };

File diff suppressed because it is too large Load Diff

@ -1,28 +1,31 @@
import * as THREE from './lib/three.module.js'; import * as THREE from "./lib/three.module.js";
import { RadarManager } from "./radar.js";
import {RadarManager} from "./radar.js" import { AuxLidarManager } from "./aux_lidar.js";
import {AuxLidarManager} from "./aux_lidar.js" import { Lidar } from "./lidar.js";
import {Lidar} from "./lidar.js" import { Annotation } from "./annotation.js";
import {Annotation} from "./annotation.js" import { EgoPose } from "./ego_pose.js";
import {EgoPose} from "./ego_pose.js" import { logger } from "./log.js";
import {logger} from "./log.js" import {
import { euler_angle_to_rotate_matrix, euler_angle_to_rotate_matrix_3by3, matmul, matmul2 , mat} from './util.js'; euler_angle_to_rotate_matrix,
euler_angle_to_rotate_matrix_3by3,
function FrameInfo(data, sceneMeta, sceneName, frame){ matmul,
matmul2,
mat,
} from "./util.js";
function FrameInfo(data, sceneMeta, sceneName, frame) {
this.data = data; this.data = data;
this.sceneMeta = sceneMeta; this.sceneMeta = sceneMeta;
this.dir = ""; this.dir = "";
this.scene = sceneName; this.scene = sceneName;
this.frame = frame; this.frame = frame;
this.pcd_ext = ""; this.pcd_ext = "";
this.frame_index = this.sceneMeta.frames.findIndex(function(x){return x==frame;}), (this.frame_index = this.sceneMeta.frames.findIndex(function (x) {
this.transform_matrix = this.sceneMeta.point_transform_matrix, return x == frame;
this.annotation_format = this.sceneMeta.boxtype, //xyz(24 number), csr(center, scale, rotation, 9 number) })),
(this.transform_matrix = this.sceneMeta.point_transform_matrix),
(this.annotation_format = this.sceneMeta.boxtype), //xyz(24 number), csr(center, scale, rotation, 9 number)
// this.set = function(scene, frame_index, frame, transform_matrix, annotation_format){ // this.set = function(scene, frame_index, frame, transform_matrix, annotation_format){
// this.scene = scene; // this.scene = scene;
// this.frame = frame; // this.frame = frame;
@ -31,44 +34,38 @@ function FrameInfo(data, sceneMeta, sceneName, frame){
// this.annotation_format = annotation_format; // this.annotation_format = annotation_format;
// }; // };
(this.get_pcd_path = function () {
this.get_pcd_path = function(){ return (
return 'data/'+ this.scene + "/lidar/" + this.frame + this.sceneMeta.lidar_ext; "data/" + this.scene + "/lidar/" + this.frame + this.sceneMeta.lidar_ext
}; );
this.get_radar_path = function(name){ });
this.get_radar_path = function (name) {
return `data/${this.scene}/radar/${name}/${this.frame}${this.sceneMeta.radar_ext}`; return `data/${this.scene}/radar/${name}/${this.frame}${this.sceneMeta.radar_ext}`;
}; };
this.get_aux_lidar_path = function(name){ this.get_aux_lidar_path = function (name) {
return `data/${this.scene}/aux_lidar/${name}/${this.frame}${this.sceneMeta.radar_ext}`; return `data/${this.scene}/aux_lidar/${name}/${this.frame}${this.sceneMeta.radar_ext}`;
} };
this.get_anno_path = function(){ this.get_anno_path = function () {
if (this.annotation_format=="psr"){ if (this.annotation_format == "psr") {
return 'data/'+this.scene + "/label/" + this.frame + ".json"; return "data/" + this.scene + "/label/" + this.frame + ".json";
} else {
return "data/" + this.scene + "/bbox.xyz/" + this.frame + ".bbox.txt";
} }
else{
return 'data/'+this.scene + "/bbox.xyz/" + this.frame + ".bbox.txt";
}
}; };
this.anno_to_boxes = function(text){ this.anno_to_boxes = function (text) {
var _self = this; var _self = this;
if (this.annotation_format == "psr"){ if (this.annotation_format == "psr") {
var boxes = JSON.parse(text); var boxes = JSON.parse(text);
return boxes; return boxes;
} } else return this.python_xyz_to_psr(text);
else
return this.python_xyz_to_psr(text);
}; };
this.transform_point = function(m, x,y, z){ this.transform_point = function (m, x, y, z) {
var rx = x*m[0]+y*m[1]+z*m[2]; var rx = x * m[0] + y * m[1] + z * m[2];
var ry = x*m[3]+y*m[4]+z*m[5]; var ry = x * m[3] + y * m[4] + z * m[5];
var rz = x*m[6]+y*m[7]+z*m[8]; var rz = x * m[6] + y * m[7] + z * m[8];
return [rx, ry, rz]; return [rx, ry, rz];
}; };
@ -80,18 +77,31 @@ function FrameInfo(data, sceneMeta, sceneName, frame){
this format is what SECOND/PointRcnn save their results. this format is what SECOND/PointRcnn save their results.
*/ */
this.python_xyz_to_psr = function(text){ this.python_xyz_to_psr = function (text) {
var _self = this; var _self = this;
var points_array = text.split('\n').filter(function(x){return x;}).map(function(x){return x.split(' ').map(function(x){return parseFloat(x);})}) var points_array = text
.split("\n")
.filter(function (x) {
return x;
})
.map(function (x) {
return x.split(" ").map(function (x) {
return parseFloat(x);
});
});
var boxes = points_array.map(function(ps){ var boxes = points_array.map(function (ps) {
for (var i=0; i<8; i++){ for (var i = 0; i < 8; i++) {
var p = _self.transform_point(_self.transform_matrix, ps[3*i+0],ps[3*i+1],ps[3*i+2]); var p = _self.transform_point(
ps[i*3+0] = p[0]; _self.transform_matrix,
ps[i*3+1] = p[1]; ps[3 * i + 0],
ps[i*3+2] = p[2]; ps[3 * i + 1],
ps[3 * i + 2]
);
ps[i * 3 + 0] = p[0];
ps[i * 3 + 1] = p[1];
ps[i * 3 + 2] = p[2];
} }
return ps; return ps;
}); });
@ -101,31 +111,36 @@ function FrameInfo(data, sceneMeta, sceneName, frame){
return boxes_ann; //, boxes]; return boxes_ann; //, boxes];
}; };
this.xyz_to_psr = function(ann_input){ this.xyz_to_psr = function (ann_input) {
var ann = []; var ann = [];
if (ann_input.length==24) if (ann_input.length == 24) ann = ann_input;
ann = ann_input;
else else
for (var i = 0; i<ann_input.length; i++){ for (var i = 0; i < ann_input.length; i++) {
if ((i+1) % 4 != 0){ if ((i + 1) % 4 != 0) {
ann.push(ann_input[i]); ann.push(ann_input[i]);
} }
} }
var pos={x:0,y:0,z:0}; var pos = { x: 0, y: 0, z: 0 };
for (var i=0; i<8; i++){ for (var i = 0; i < 8; i++) {
pos.x+=ann[i*3]; pos.x += ann[i * 3];
pos.y+=ann[i*3+1]; pos.y += ann[i * 3 + 1];
pos.z+=ann[i*3+2]; pos.z += ann[i * 3 + 2];
} }
pos.x /=8; pos.x /= 8;
pos.y /=8; pos.y /= 8;
pos.z /=8; pos.z /= 8;
var scale={ var scale = {
x: Math.sqrt((ann[0]-ann[3])*(ann[0]-ann[3])+(ann[1]-ann[4])*(ann[1]-ann[4])), x: Math.sqrt(
y: Math.sqrt((ann[0]-ann[9])*(ann[0]-ann[9])+(ann[1]-ann[10])*(ann[1]-ann[10])), (ann[0] - ann[3]) * (ann[0] - ann[3]) +
z: ann[14]-ann[2], (ann[1] - ann[4]) * (ann[1] - ann[4])
),
y: Math.sqrt(
(ann[0] - ann[9]) * (ann[0] - ann[9]) +
(ann[1] - ann[10]) * (ann[1] - ann[10])
),
z: ann[14] - ann[2],
}; };
/* /*
@ -135,21 +150,23 @@ function FrameInfo(data, sceneMeta, sceneName, frame){
3 2 3 2
*/ */
var angle = Math.atan2(ann[4]+ann[7]-2*pos.y, ann[3]+ann[6]-2*pos.x); var angle = Math.atan2(
ann[4] + ann[7] - 2 * pos.y,
ann[3] + ann[6] - 2 * pos.x
);
return { return {
position: pos, position: pos,
scale:scale, scale: scale,
rotation:{x:0,y:0,z:angle}, rotation: { x: 0, y: 0, z: angle },
} };
}; };
} }
function Images(sceneMeta, sceneName, frame){ function Images(sceneMeta, sceneName, frame) {
this.loaded = function(){ this.loaded = function () {
for (var n in this.names){ for (var n in this.names) {
if (!this.loaded_flag[this.names[n]]) if (!this.loaded_flag[this.names[n]]) return false;
return false;
} }
return true; return true;
@ -161,7 +178,7 @@ function Images(sceneMeta, sceneName, frame){
// this.active_image = function(){ // this.active_image = function(){
// return this.content[this.active_name]; // return this.content[this.active_name];
// }; // };
this.getImageByName = function(name){ this.getImageByName = function (name) {
return this.content[name]; return this.content[name];
}; };
@ -172,7 +189,7 @@ function Images(sceneMeta, sceneName, frame){
this.content = {}; this.content = {};
this.on_all_loaded = null; this.on_all_loaded = null;
this.load = function(on_all_loaded, active_name){ (this.load = function (on_all_loaded, active_name) {
this.on_all_loaded = on_all_loaded; this.on_all_loaded = on_all_loaded;
// if global camera not set, use first camera as default. // if global camera not set, use first camera as default.
@ -183,45 +200,47 @@ function Images(sceneMeta, sceneName, frame){
var _self = this; var _self = this;
if (this.names){ if (this.names) {
this.names.forEach(function(cam){ this.names.forEach(function (cam) {
_self.content[cam] = new Image(); _self.content[cam] = new Image();
_self.content[cam].onload= function(){ _self.content[cam].onload = function () {
_self.loaded_flag[cam] = true; _self.loaded_flag[cam] = true;
_self.on_image_loaded(); _self.on_image_loaded();
}; };
_self.content[cam].onerror=function(){ _self.content[cam].onerror = function () {
_self.loaded_flag[cam] = true; _self.loaded_flag[cam] = true;
_self.on_image_loaded(); _self.on_image_loaded();
}; };
_self.content[cam].src = 'data/'+sceneName+'/camera/' + cam + '/'+ frame + sceneMeta.camera_ext; _self.content[cam].src =
console.log("image set") "data/" +
sceneName +
"/camera/" +
cam +
"/" +
frame +
sceneMeta.camera_ext;
console.log("image set");
}); });
} }
}, }),
(this.on_image_loaded = function () {
this.on_image_loaded = function(){ if (this.loaded()) {
if (this.loaded()){
this.on_all_loaded(); this.on_all_loaded();
} }
} });
} }
function World(data, sceneName, frame, coordinatesOffset, on_preload_finished) {
function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
this.data = data; this.data = data;
this.sceneMeta = this.data.getMetaBySceneName(sceneName); this.sceneMeta = this.data.getMetaBySceneName(sceneName);
this.frameInfo = new FrameInfo(this.data, this.sceneMeta, sceneName, frame); this.frameInfo = new FrameInfo(this.data, this.sceneMeta, sceneName, frame);
this.coordinatesOffset = coordinatesOffset; this.coordinatesOffset = coordinatesOffset;
this.toString = function () {
this.toString = function(){
return this.frameInfo.scene + "," + this.frameInfo.frame; return this.frameInfo.scene + "," + this.frameInfo.frame;
} };
//points_backup: null, //for restore from highlight //points_backup: null, //for restore from highlight
this.cameras = new Images(this.sceneMeta, sceneName, frame); this.cameras = new Images(this.sceneMeta, sceneName, frame);
@ -234,54 +253,49 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
// todo: state of world could be put in a variable // todo: state of world could be put in a variable
// but still need mulitple flags. // but still need mulitple flags.
this.points_loaded = false, (this.points_loaded = false),
(this.preloaded = function () {
return (
this.lidar.preloaded &&
this.preloaded=function(){
return this.lidar.preloaded &&
this.annotation.preloaded && this.annotation.preloaded &&
//this.cameras.loaded() && //this.cameras.loaded() &&
this.aux_lidars.preloaded() && this.aux_lidars.preloaded() &&
this.radars.preloaded()&& this.radars.preloaded() &&
this.egoPose.preloaded; this.egoPose.preloaded
}; );
});
this.create_time = 0; this.create_time = 0;
this.finish_time = 0; this.finish_time = 0;
this.on_preload_finished = null; this.on_preload_finished = null;
this.on_subitem_preload_finished = function(on_preload_finished){ this.on_subitem_preload_finished = function (on_preload_finished) {
if (this.preloaded()){ if (this.preloaded()) {
logger.log(
logger.log(`finished preloading ${this.frameInfo.scene} ${this.frameInfo.frame}`); `finished preloading ${this.frameInfo.scene} ${this.frameInfo.frame}`
);
this.calcTransformMatrix(); this.calcTransformMatrix();
if (this.on_preload_finished) {
if (this.on_preload_finished){
this.on_preload_finished(this); this.on_preload_finished(this);
} }
if (this.active){ if (this.active) {
this.go(); this.go();
} }
} }
}; };
this.calcTransformMatrix = function () {
this.calcTransformMatrix = function() if (this.egoPose.egoPose) {
{
if (this.egoPose.egoPose){
let thisPose = this.egoPose.egoPose; let thisPose = this.egoPose.egoPose;
let refPose = this.data.getRefEgoPose(this.frameInfo.scene, thisPose); let refPose = this.data.getRefEgoPose(this.frameInfo.scene, thisPose);
let thisRot = { let thisRot = {
x: thisPose.pitch * Math.PI/180.0, x: (thisPose.pitch * Math.PI) / 180.0,
y: thisPose.roll * Math.PI/180.0, y: (thisPose.roll * Math.PI) / 180.0,
z: - thisPose.azimuth * Math.PI/180.0 z: (-thisPose.azimuth * Math.PI) / 180.0,
}; };
let posDelta = { let posDelta = {
@ -290,8 +304,6 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
z: thisPose.z - refPose.z, z: thisPose.z - refPose.z,
}; };
//console.log("pose", thisPose, refPose, delta); //console.log("pose", thisPose, refPose, delta);
//let theta = delta.rotation.z*Math.PI/180.0; //let theta = delta.rotation.z*Math.PI/180.0;
@ -302,15 +314,24 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
// this should be a calib matrix // this should be a calib matrix
//let trans_lidar_ego = euler_angle_to_rotate_matrix({x: 0, y: 0, z: Math.PI}, {x:0, y:0, z:0.4}); //let trans_lidar_ego = euler_angle_to_rotate_matrix({x: 0, y: 0, z: Math.PI}, {x:0, y:0, z:0.4});
let trans_lidar_ego = new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(0,0,Math.PI, "ZYX")) let trans_lidar_ego = new THREE.Matrix4()
.makeRotationFromEuler(new THREE.Euler(0, 0, Math.PI, "ZYX"))
.setPosition(0, 0, 0.4); .setPosition(0, 0, 0.4);
//let trans_ego_utm = euler_angle_to_rotate_matrix(thisRot, posDelta, "ZXY"); //let trans_ego_utm = euler_angle_to_rotate_matrix(thisRot, posDelta, "ZXY");
let trans_ego_utm = new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(thisRot.x, thisRot.y, thisRot.z, "ZXY")) let trans_ego_utm = new THREE.Matrix4()
.makeRotationFromEuler(
new THREE.Euler(thisRot.x, thisRot.y, thisRot.z, "ZXY")
)
.setPosition(posDelta.x, posDelta.y, posDelta.z); .setPosition(posDelta.x, posDelta.y, posDelta.z);
let trans_utm_scene = new THREE.Matrix4().identity().setPosition(this.coordinatesOffset[0], this.coordinatesOffset[1], this.coordinatesOffset[2]); let trans_utm_scene = new THREE.Matrix4()
.identity()
.setPosition(
this.coordinatesOffset[0],
this.coordinatesOffset[1],
this.coordinatesOffset[2]
);
// let offset_ego = matmul(trans_utm_ego, [delta.position.x, delta.position.y, delta.position.z], 3); // let offset_ego = matmul(trans_utm_ego, [delta.position.x, delta.position.y, delta.position.z], 3);
// let offset_lidar = matmul(trans_ego_lidar, offset_ego, 3); // let offset_lidar = matmul(trans_ego_lidar, offset_ego, 3);
@ -326,186 +347,196 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
// 0, 0, 0, 1, // 0, 0, 0, 1,
// ]; // ];
this.trans_lidar_utm = new THREE.Matrix4().multiplyMatrices(trans_ego_utm, trans_lidar_ego); this.trans_lidar_utm = new THREE.Matrix4().multiplyMatrices(
trans_ego_utm,
trans_lidar_ego
);
if (this.data.cfg.coordinateSystem == "utm") if (this.data.cfg.coordinateSystem == "utm")
this.trans_lidar_scene = new THREE.Matrix4().multiplyMatrices(trans_utm_scene, this.trans_lidar_utm); this.trans_lidar_scene = new THREE.Matrix4().multiplyMatrices(
else trans_utm_scene,
this.trans_lidar_scene = trans_utm_scene; //only offset. this.trans_lidar_utm
);
this.trans_utm_lidar = new THREE.Matrix4().copy(this.trans_lidar_utm).invert(); else this.trans_lidar_scene = trans_utm_scene; //only offset.
this.trans_scene_lidar = new THREE.Matrix4().copy(this.trans_lidar_scene).invert();
this.trans_utm_lidar = new THREE.Matrix4()
.copy(this.trans_lidar_utm)
} .invert();
else this.trans_scene_lidar = new THREE.Matrix4()
{ .copy(this.trans_lidar_scene)
let trans_utm_scene = new THREE.Matrix4().identity().setPosition(this.coordinatesOffset[0], this.coordinatesOffset[1], this.coordinatesOffset[2]); .invert();
} else {
let trans_utm_scene = new THREE.Matrix4()
.identity()
.setPosition(
this.coordinatesOffset[0],
this.coordinatesOffset[1],
this.coordinatesOffset[2]
);
let id = new THREE.Matrix4().identity(); let id = new THREE.Matrix4().identity();
this.trans_lidar_utm = id; this.trans_lidar_utm = id;
this.trans_lidar_scene = trans_utm_scene; this.trans_lidar_scene = trans_utm_scene;
this.trans_utm_lidar = new THREE.Matrix4().copy(this.trans_lidar_utm).invert(); this.trans_utm_lidar = new THREE.Matrix4()
this.trans_scene_lidar = new THREE.Matrix4().copy(this.trans_lidar_scene).invert(); .copy(this.trans_lidar_utm)
.invert();
this.trans_scene_lidar = new THREE.Matrix4()
.copy(this.trans_lidar_scene)
.invert();
} }
this.webglGroup.matrix.copy(this.trans_lidar_scene); this.webglGroup.matrix.copy(this.trans_lidar_scene);
this.webglGroup.matrixAutoUpdate = false; this.webglGroup.matrixAutoUpdate = false;
}; };
// global scene // global scene
this.scenePosToLidar = function(pos) this.scenePosToLidar = function (pos) {
{ let tp = new THREE.Vector4(pos.x, pos.y, pos.z, 1).applyMatrix4(
let tp = new THREE.Vector4(pos.x, pos.y, pos.z, 1).applyMatrix4(this.trans_scene_lidar); this.trans_scene_lidar
);
return tp; return tp;
} };
// global scene // global scene
this.lidarPosToScene = function(pos) this.lidarPosToScene = function (pos) {
{ let tp = new THREE.Vector3(pos.x, pos.y, pos.z).applyMatrix4(
let tp = new THREE.Vector3(pos.x, pos.y, pos.z).applyMatrix4(this.trans_lidar_scene); this.trans_lidar_scene
);
return tp; return tp;
} };
// global scene // global scene
this.lidarPosToUtm = function(pos) this.lidarPosToUtm = function (pos) {
{ let tp = new THREE.Vector3(pos.x, pos.y, pos.z).applyMatrix4(
let tp = new THREE.Vector3(pos.x, pos.y, pos.z).applyMatrix4(this.trans_lidar_utm); this.trans_lidar_utm
);
return tp; return tp;
} };
this.sceneRotToLidar = function(rotEuler) this.sceneRotToLidar = function (rotEuler) {
{ if (!rotEuler.isEuler) {
if (!rotEuler.isEuler)
{
rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ"); rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ");
} }
let rotG = new THREE.Quaternion().setFromEuler(rotEuler); let rotG = new THREE.Quaternion().setFromEuler(rotEuler);
let GlobalToLocalRot = new THREE.Quaternion().setFromRotationMatrix(this.trans_scene_lidar); let GlobalToLocalRot = new THREE.Quaternion().setFromRotationMatrix(
this.trans_scene_lidar
);
let retQ = rotG.multiply(GlobalToLocalRot); let retQ = rotG.multiply(GlobalToLocalRot);
let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order); let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order);
return retEuler; return retEuler;
} };
this.lidarRotToScene = function(rotEuler) this.lidarRotToScene = function (rotEuler) {
{ if (!rotEuler.isEuler) {
if (!rotEuler.isEuler)
{
rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ"); rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ");
} }
let rotL = new THREE.Quaternion().setFromEuler(rotEuler); let rotL = new THREE.Quaternion().setFromEuler(rotEuler);
let localToGlobalRot = new THREE.Quaternion().setFromRotationMatrix(this.trans_lidar_scene) let localToGlobalRot = new THREE.Quaternion().setFromRotationMatrix(
this.trans_lidar_scene
);
let retQ = rotL.multiply(localToGlobalRot); let retQ = rotL.multiply(localToGlobalRot);
let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order); let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order);
return retEuler; return retEuler;
} };
this.lidarRotToUtm = function(rotEuler) this.lidarRotToUtm = function (rotEuler) {
{ if (!rotEuler.isEuler) {
if (!rotEuler.isEuler)
{
rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ"); rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ");
} }
let rotL = new THREE.Quaternion().setFromEuler(rotEuler); let rotL = new THREE.Quaternion().setFromEuler(rotEuler);
let localToGlobalRot = new THREE.Quaternion().setFromRotationMatrix(this.trans_lidar_utm) let localToGlobalRot = new THREE.Quaternion().setFromRotationMatrix(
this.trans_lidar_utm
);
let retQ = rotL.multiply(localToGlobalRot); let retQ = rotL.multiply(localToGlobalRot);
let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order); let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order);
return retEuler; return retEuler;
} };
this.utmRotToLidar = function(rotEuler) this.utmRotToLidar = function (rotEuler) {
{ if (!rotEuler.isEuler) {
if (!rotEuler.isEuler)
{
rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ"); rotEuler = new THREE.Euler(rotEuler.x, rotEuler.y, rotEuler.z, "XYZ");
} }
let rot = new THREE.Quaternion().setFromEuler(rotEuler); let rot = new THREE.Quaternion().setFromEuler(rotEuler);
let trans = new THREE.Quaternion().setFromRotationMatrix(this.trans_utm_lidar); let trans = new THREE.Quaternion().setFromRotationMatrix(
this.trans_utm_lidar
);
let retQ = rot.multiply(trans); let retQ = rot.multiply(trans);
let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order); let retEuler = new THREE.Euler().setFromQuaternion(retQ, rotEuler.order);
return retEuler; return retEuler;
} };
this.preload=function(on_preload_finished){ this.preload = function (on_preload_finished) {
this.create_time = new Date().getTime(); this.create_time = new Date().getTime();
console.log(this.create_time, sceneName, frame, "start"); console.log(this.create_time, sceneName, frame, "start");
this.webglGroup = new THREE.Group(); this.webglGroup = new THREE.Group();
this.webglGroup.name = "world"; this.webglGroup.name = "world";
let _preload_cb = () =>
let _preload_cb = ()=>this.on_subitem_preload_finished(on_preload_finished); this.on_subitem_preload_finished(on_preload_finished);
this.lidar.preload(_preload_cb); this.lidar.preload(_preload_cb);
this.annotation.preload(_preload_cb) this.annotation.preload(_preload_cb);
this.radars.preload(_preload_cb); this.radars.preload(_preload_cb);
this.cameras.load(_preload_cb, this.data.active_camera_name); this.cameras.load(_preload_cb, this.data.active_camera_name);
this.aux_lidars.preload(_preload_cb); this.aux_lidars.preload(_preload_cb);
this.egoPose.preload(_preload_cb); this.egoPose.preload(_preload_cb);
}; };
this.scene = null, (this.scene = null),
this.destroy_old_world = null, //todo, this can be a boolean (this.destroy_old_world = null), //todo, this can be a boolean
this.on_finished = null, (this.on_finished = null),
this.activate=function(scene, destroy_old_world, on_finished){ (this.activate = function (scene, destroy_old_world, on_finished) {
this.scene = scene; this.scene = scene;
this.active = true; this.active = true;
this.destroy_old_world = destroy_old_world; this.destroy_old_world = destroy_old_world;
this.on_finished = on_finished; this.on_finished = on_finished;
if (this.preloaded()){ if (this.preloaded()) {
this.go(); this.go();
} }
}; });
this.active = false,
this.everythingDone = false;
this.go=function(){ (this.active = false), (this.everythingDone = false);
if (this.everythingDone){ this.go = function () {
if (this.everythingDone) {
//console.error("re-activate world?"); //console.error("re-activate world?");
//however we still call on_finished //however we still call on_finished
if (this.on_finished){ if (this.on_finished) {
this.on_finished(); this.on_finished();
} }
return; return;
} }
if (this.preloaded()){ if (this.preloaded()) {
//this.points.material.size = data.cfg.point_size; //this.points.material.size = data.cfg.point_size;
if (this.destroy_old_world){ if (this.destroy_old_world) {
this.destroy_old_world(); this.destroy_old_world();
} }
if (this.destroyed){ if (this.destroyed) {
console.log("go after destroyed."); console.log("go after destroyed.");
this.unload(); this.unload();
return; return;
@ -518,13 +549,18 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
this.radars.go(this.scene); this.radars.go(this.scene);
this.aux_lidars.go(this.scene); this.aux_lidars.go(this.scene);
this.finish_time = new Date().getTime(); this.finish_time = new Date().getTime();
console.log(this.finish_time, sceneName, frame, "loaded in ", this.finish_time - this.create_time, "ms"); console.log(
this.finish_time,
sceneName,
frame,
"loaded in ",
this.finish_time - this.create_time,
"ms"
);
// render is called in on_finished() callback // render is called in on_finished() callback
if (this.on_finished){ if (this.on_finished) {
this.on_finished(); this.on_finished();
} }
@ -532,37 +568,36 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
} }
}; };
this.add_line = function (start, end, color) {
this.add_line=function(start, end, color){
var line = this.new_line(start, end, color); var line = this.new_line(start, end, color);
this.scene.add(line); this.scene.add(line);
}; };
this.new_line = function (start, end, color) {
this.new_line=function(start, end, color){
var vertex = start.concat(end); var vertex = start.concat(end);
this.world.data.dbg.alloc(); this.world.data.dbg.alloc();
var line = new THREE.BufferGeometry(); var line = new THREE.BufferGeometry();
line.addAttribute( 'position', new THREE.Float32BufferAttribute(vertex, 3 ) ); line.addAttribute("position", new THREE.Float32BufferAttribute(vertex, 3));
if (!color){ if (!color) {
color = 0x00ff00; color = 0x00ff00;
} }
var material = new THREE.LineBasicMaterial( { color: color, linewidth: 1, opacity: this.data.cfg.box_opacity, transparent: true } ); var material = new THREE.LineBasicMaterial({
return new THREE.LineSegments( line, material ); color: color,
linewidth: 1,
opacity: this.data.cfg.box_opacity,
transparent: true,
});
return new THREE.LineSegments(line, material);
}; };
this.destroyed = false; this.destroyed = false;
// todo, Image resource to be released? // todo, Image resource to be released?
this.unload = function(){ this.unload = function () {
if (this.everythingDone){ if (this.everythingDone) {
//unload all from scene, but don't destroy elements //unload all from scene, but don't destroy elements
this.lidar.unload(); this.lidar.unload();
this.radars.unload(); this.radars.unload();
@ -576,19 +611,17 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
} }
}; };
this.deleteAll = function () {
var _self = this;
this.deleteAll = function(){
var _self= this;
logger.log(`delete world ${this.frameInfo.scene},${this.frameInfo.frame}`); logger.log(`delete world ${this.frameInfo.scene},${this.frameInfo.frame}`);
if (this.everythingDone){ if (this.everythingDone) {
this.unload(); this.unload();
} }
// todo, check if all objects are removed from webgl scene. // todo, check if all objects are removed from webgl scene.
if (this.destroyed){ if (this.destroyed) {
console.log("destroy destroyed world!"); console.log("destroy destroyed world!");
} }
@ -605,5 +638,4 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
this.preload(on_preload_finished); this.preload(on_preload_finished);
} }
export {World}; export { World };

Loading…
Cancel
Save