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

main
陈炎群 5 months ago
parent f374f4c12c
commit d4602681c7

@ -1,10 +1,7 @@
import * as THREE from "./lib/three.module.js";
import { globalObjectCategory } from "./obj_cfg.js";
import * as THREE from './lib/three.module.js'; import { saveWorldList } from "./save.js";
import {globalObjectCategory} from './obj_cfg.js'; import { intersect } from "./util.js";
import {saveWorldList} from "./save.js"
import { intersect } from './util.js';
function Annotation(sceneMeta, world, frameInfo) { function Annotation(sceneMeta, world, frameInfo) {
this.world = world; this.world = world;
@ -13,18 +10,17 @@ function Annotation(sceneMeta, world, frameInfo){
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) {
@ -43,7 +39,7 @@ function Annotation(sceneMeta, world, frameInfo){
}; };
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) {
@ -51,8 +47,6 @@ function Annotation(sceneMeta, world, frameInfo){
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;
@ -60,21 +54,18 @@ function Annotation(sceneMeta, world, frameInfo){
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;
@ -88,14 +79,12 @@ function Annotation(sceneMeta, world, frameInfo){
} }
}; };
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();
}); });
} }
}; };
@ -135,11 +124,9 @@ function Annotation(sceneMeta, world, frameInfo){
//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;
}); });
@ -148,27 +135,31 @@ function Annotation(sceneMeta, world, frameInfo){
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);
@ -177,12 +168,10 @@ function Annotation(sceneMeta, world, frameInfo){
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],
@ -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,14 +308,12 @@ 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,8 +324,12 @@ function Annotation(sceneMeta, world, frameInfo){
linewidth is 1, regardless of set value. linewidth is 1, regardless of set value.
*/ */
var material = new THREE.LineBasicMaterial({
var material = new THREE.LineBasicMaterial( { color: color, linewidth: 1, opacity: this.data.cfg.box_opacity, transparent: true } ); color: color,
linewidth: 1,
opacity: this.data.cfg.box_opacity,
transparent: true,
});
var box = new THREE.LineSegments(bbox, material); var box = new THREE.LineSegments(bbox, material);
box.scale.x = 1.8; box.scale.x = 1.8;
@ -287,13 +340,22 @@ function Annotation(sceneMeta, world, frameInfo){
//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;
@ -320,8 +382,14 @@ function Annotation(sceneMeta, world, frameInfo){
*/ */
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();
@ -332,12 +400,10 @@ function Annotation(sceneMeta, world, frameInfo){
}; };
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);
}; };
@ -346,7 +412,9 @@ function Annotation(sceneMeta, world, frameInfo){
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) {
@ -357,28 +425,24 @@ function Annotation(sceneMeta, world, frameInfo){
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();
@ -391,18 +455,15 @@ function Annotation(sceneMeta, world, frameInfo){
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,17 +473,24 @@ 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) {
@ -442,43 +510,65 @@ 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 = []; let pendingBoxList = [];
boxes.forEach(nb=>{ // nb is annotation format, not a true box boxes.forEach((nb) => {
// nb is annotation format, not a true box
let old_box = this.boxes.find(function (x) { 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;; 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);
@ -487,22 +577,20 @@ function Annotation(sceneMeta, world, frameInfo){
}); });
// 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,34 +601,32 @@ 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;
}; };
@ -551,7 +637,6 @@ function Annotation(sceneMeta, world, frameInfo){
}); });
}; };
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;
@ -559,33 +644,28 @@ function Annotation(sceneMeta, world, frameInfo){
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,12 +1,15 @@
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;
@ -17,7 +20,7 @@ function AutoAdjust(boxOp, mouse, header){
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}`);
@ -27,14 +30,16 @@ 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,36 +47,40 @@ 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,11 +101,9 @@ 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)),
@ -105,8 +112,7 @@ function AutoAdjust(boxOp, mouse, header){
}; };
}); });
candPoseSets = candPoseSets.filter(p=>!!p); candPoseSets = candPoseSets.filter((p) => !!p);
if (candPoseSets.length == 0) { if (candPoseSets.length == 0) {
return; return;
@ -117,7 +123,7 @@ function AutoAdjust(boxOp, mouse, header){
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,14 +144,16 @@ 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;
} }
} }
@ -166,15 +174,16 @@ function AutoAdjust(boxOp, mouse, header){
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);
@ -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(
(b) => b.obj_track_id == this.marked_object.ann.obj_id
);
if (refObj) { 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,22 +225,25 @@ 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(
(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; return;
@ -248,7 +261,7 @@ 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) {
@ -277,12 +290,14 @@ 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,
@ -309,7 +324,9 @@ 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");
@ -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,
]; ];
@ -339,17 +356,19 @@ 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;
@ -433,12 +446,11 @@ 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,7 +1,5 @@
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
@ -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,7 +1,6 @@
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
@ -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,7 +30,6 @@ 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;
@ -44,15 +40,11 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
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
@ -76,8 +68,7 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
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 [];
} }
}; };
@ -87,10 +78,9 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
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;
}; };
@ -105,19 +95,17 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
//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;
@ -134,16 +122,12 @@ 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]);
} }
} }
} }
@ -152,18 +136,17 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
}; };
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;
@ -179,15 +162,12 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
//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,
@ -221,12 +201,21 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
}; };
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 },
{ {
@ -235,17 +224,20 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
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.5, y: 0.5, z: 0.5 },
{ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 },
"lidar", "lidar",
this.name); this.name
);
} }
}; };
@ -254,28 +246,31 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
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;
@ -286,7 +281,6 @@ function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
return mesh; return mesh;
}; };
this.buildGeometry = function (position) { this.buildGeometry = function (position) {
let points = this.buildPoints(position); let points = this.buildPoints(position);
@ -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,11 +313,11 @@ 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));
} }
}; };
} }
@ -338,66 +329,59 @@ function AuxLidarManager(sceneMeta, world, frameInfo){
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,5 +1,9 @@
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) {
@ -10,15 +14,14 @@ function Calib(data, editor){
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 = {
@ -27,20 +30,18 @@ function Calib(data, editor){
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;
@ -48,31 +49,60 @@ function Calib(data, editor){
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,
-1,
0,
0, //row vector
0,
0,
-1,
0,
1,
0,
0,
0,
0,
0,
0,
1,
];
function transpose_transmatrix(m) { 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 = {
@ -84,9 +114,7 @@ function Calib(data, editor){
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],
@ -97,16 +125,14 @@ function Calib(data, editor){
{ {
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];
@ -120,7 +146,6 @@ 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.");
@ -130,22 +155,21 @@ function Calib(data, editor){
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(
this.calib_box.rotation,
real_pos
);
calib.extrinsic = transpose_transmatrix(matmul(viewMatrix, extrinsic, 4)); calib.extrinsic = transpose_transmatrix(matmul(viewMatrix, extrinsic, 4));
console.log("extrinsic", calib.extrinsic) 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;
@ -25,7 +23,6 @@ class Config{
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;
@ -58,37 +55,26 @@ 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";
} }
@ -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 };

@ -2,7 +2,6 @@ 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);
@ -62,17 +61,14 @@ class ConfigUi{
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);
@ -89,27 +85,21 @@ class ConfigUi{
//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);
@ -128,7 +118,7 @@ class ConfigUi{
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;
@ -138,7 +128,7 @@ class ConfigUi{
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();
}); });
@ -172,7 +162,7 @@ class ConfigUi{
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();
@ -206,13 +196,11 @@ class ConfigUi{
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;
@ -243,105 +227,109 @@ class ConfigUi{
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 = {
@ -18,19 +16,16 @@ class ContextMenu {
}; };
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,18 +37,15 @@ 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;
} }
@ -68,34 +60,29 @@ class ContextMenu {
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();
@ -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 {
else{
if (this.wrapperUi.clientHeight < posY + menu.clientHeight) { if (this.wrapperUi.clientHeight < posY + menu.clientHeight) {
menu.style.top = (this.wrapperUi.clientHeight - menu.clientHeight) + "px"; menu.style.top = this.wrapperUi.clientHeight - menu.clientHeight + "px";
} } else {
else{
menu.style.top = posY + "px"; 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 {
else{
menu.style.left = posX + "px"; 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,7 +9,6 @@ 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) => {
@ -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 =
parseInt(frameInfo.frame) - 10;
this.ui.querySelector("#scene-seconds").value = 20; 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,42 +1,34 @@
import { World } from "./world.js"; import { World } from "./world.js";
import { Debug } from "./debug.js"; import { Debug } from "./debug.js";
import {logger} from "./log.js" import { logger } from "./log.js";
class Data
{
constructor(cfg) 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!");
}); });
} }
@ -58,79 +50,75 @@ class Data
// 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) { _createWorld(sceneName, frame, on_preload_finished) {
let [x, y, z] = this.allocateOffset(); let [x, y, z] = this.allocateOffset();
console.log("create world", x, y, z); console.log("create world", x, y, z);
let world = new World(this, sceneName, frame, [this.worldGap*x, this.worldGap*y, this.worldGap*z], on_preload_finished); let world = new World(
this,
sceneName,
frame,
[this.worldGap * x, this.worldGap * y, this.worldGap * z],
on_preload_finished
);
world.offsetIndex = [x, y, z]; world.offsetIndex = [x, y, z];
this.createWorldIndex++; this.createWorldIndex++;
this.worldList.push(world); this.worldList.push(world);
return world; return world;
}
};
findWorld(sceneName, frameIndex) { findWorld(sceneName, frameIndex) {
let world = this.worldList.find((w) => { let world = this.worldList.find((w) => {
return 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) {
if (this.offsetList.length == 0)
{
let [x, y, z] = this.lastSeedOffset; let [x, y, z] = this.lastSeedOffset;
if (x == y) if (x == y) {
{
x = x + 1; x = x + 1;
y = 0; y = 0;
} } else {
else
{
y = y + 1; y = y + 1;
} }
@ -155,70 +143,65 @@ 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) {
@ -227,7 +210,10 @@ class Data
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);
@ -235,37 +221,35 @@ class Data
} }
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,18 +260,18 @@ 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) {
@ -301,10 +285,10 @@ class Data
// 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;
@ -313,33 +297,30 @@ class Data
// 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 = "";
@ -409,60 +386,51 @@ class Data
// }; // };
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(
this.webglMainScene,
function () { function () {
if (old_world) if (old_world) old_world.unload();
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 };

@ -11,8 +11,7 @@ function Debug(){
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;
@ -45,34 +35,31 @@ class EgoPose
// 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) 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;
} }
};
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,11 +1,8 @@
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;
@ -13,31 +10,25 @@ class FastToolBox{
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;
} }
@ -49,18 +40,15 @@ class FastToolBox{
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) {
@ -68,38 +56,31 @@ class FastToolBox{
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;
@ -107,85 +88,68 @@ class FastToolBox{
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);
} }
@ -194,16 +158,13 @@ class FastToolBox{
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);
@ -283,45 +247,38 @@ class FloatLabelManager {
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.
@ -341,7 +298,6 @@ class FloatLabelManager {
} }
remove_all_labels() { remove_all_labels() {
var _self = this; var _self = this;
if (this.labelsUi.children.length > 0) { if (this.labelsUi.children.length > 0) {
@ -351,7 +307,6 @@ class FloatLabelManager {
} }
} }
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++) {
@ -360,29 +315,24 @@ class FloatLabelManager {
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,7 +340,6 @@ 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) {
@ -409,7 +358,6 @@ class FloatLabelManager {
} }
} }
set_object_track_id(local_id, track_id) { set_object_track_id(local_id, track_id) {
var label = this.editor_ui.querySelector("#obj-local-" + local_id); var label = this.editor_ui.querySelector("#obj-local-" + local_id);
@ -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,22 +381,23 @@ 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) { if (label) {
label.vertices = this.translate_vertices_to_global(
label.vertices = this.translate_vertices_to_global(box.world, psr_to_xyz(box.position, box.scale, box.rotation)); 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) {
@ -457,26 +407,20 @@ class FloatLabelManager {
} }
} }
remove_box(box) { remove_box(box) {
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) if (label) label.remove();
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); label.className = "float-label color-" + (label.obj_track_id % 33);
} } // by id
else // by id else {
{
label.className = "float-label " + label.obj_type; label.className = "float-label " + label.obj_type;
} }
@ -484,10 +428,7 @@ class FloatLabelManager {
} }
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;
@ -496,21 +437,20 @@ class FloatLabelManager {
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,15 +459,18 @@ 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";
@ -541,17 +484,24 @@ class FloatLabelManager {
}; };
} }
coord_to_pixel(p) { coord_to_pixel(p) {
var width = this.container.clientWidth, height = this.container.clientHeight; var width = this.container.clientWidth,
var widthHalf = width / 2, heightHalf = height / 2; height = this.container.clientHeight;
var widthHalf = width / 2,
heightHalf = height / 2;
var ret = { var ret = {
x: ( p.x * widthHalf ) + widthHalf + 10, x: p.x * widthHalf + widthHalf + 10,
y: -(p.y * heightHalf) + heightHalf - 10, 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, 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;
} }
@ -559,7 +509,11 @@ class FloatLabelManager {
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) {
@ -582,11 +536,10 @@ class FloatLabelManager {
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,7 +26,6 @@ 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";
} }
@ -35,122 +40,153 @@ var Header=function(ui, data, cfg, onSceneChanged, onFrameChanged, onObjectSelec
// 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 +
"</span> ";
if (box.follows) { if (box.follows) {
this.boxUi.innerHTML += "| F:" + box.follows.obj_track_id; 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 =
this.refObjUi.innerHTML="| Ref: "+marked_object.scene+"/"+marked_object.frame+": "+marked_object.ann.obj_type+"-"+marked_object.ann.obj_id; "| Ref: " +
}, marked_object.scene +
"/" +
this.set_frame_info =function(scene, frame, on_scene_changed){ marked_object.frame +
": " +
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) { 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,79 +1,61 @@
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) { showButtons(btns) {
for (let btn in this.buttons) for (let btn in this.buttons) {
{ this.buttons[btn].style.display = "none";
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();
@ -83,8 +65,7 @@ class InfoBox extends PopupDialog{
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,7 +14,9 @@ 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");
@ -30,61 +26,73 @@ class LogWindow extends PopupDialog{
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
.querySelectorAll(".log-object-frame-id")
.forEach((ele) => {
ele.onclick = (event) => { 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,17 +128,22 @@ 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,20 +195,15 @@ 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) {

@ -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) => {
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()
} }
}); });
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,24 +1,26 @@
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;
} }
@ -27,36 +29,30 @@ const annMath = {
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;
} }
} }
@ -65,34 +61,28 @@ const annMath = {
}, },
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(),
@ -102,17 +92,23 @@ var ml = {
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 &&
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]) { 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;
} }
@ -125,31 +121,33 @@ var ml = {
} }
//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) { var data_centered = points_2d.map(function (x) {
return [ return [x[0] - mean[0], x[1] - mean[1], x[2] - mean[2]];
x[0] - mean[0], });
x[1] - mean[1],
x[2] - mean[2],
];
})
var normal_v = this.train(data_centered); var normal_v = this.train(data_centered);
data.world.add_line(mean, [
-normal_v[0] * 10,
data.world.add_line(mean, [-normal_v[0]*10, -normal_v[1]*10, normal_v[2]*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()]]));
@ -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);
@ -229,9 +222,11 @@ 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
@ -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
@ -287,30 +279,28 @@ var ml = {
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])) {
@ -327,39 +317,34 @@ var ml = {
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,10 +353,12 @@ 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;
@ -380,11 +367,9 @@ var ml = {
// 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]);
@ -404,8 +389,7 @@ var ml = {
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++;
} }
@ -435,8 +416,7 @@ var ml = {
//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]);
@ -450,57 +430,51 @@ var ml = {
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;
@ -516,27 +490,25 @@ function MaFilter_tf(initX){ // moving average filter
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;
@ -552,7 +524,6 @@ function MaFilter(initX){ // moving average filter
this.x = x; this.x = x;
this.step++; this.step++;
}; };
} }
export { ml, MaFilter }; export { ml, MaFilter };

@ -1,30 +1,42 @@
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,
parentUi,
on_left_click,
on_right_click,
on_select_rect
) {
this.view = view; 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;
@ -40,7 +52,6 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
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;
@ -56,18 +67,14 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
return { x: x, y: y, z: 0 }; return { x: x, y: y, z: 0 };
}; };
this.getMousePosition = function (dom, offsetX, offsetY) { this.getMousePosition = function (dom, offsetX, offsetY) {
return [
(offsetX / dom.clientWidth) * 2 - 1,
return [offsetX/dom.clientWidth * 2 - 1, - offsetY/dom.clientHeight * 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);
@ -75,12 +82,9 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
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) {
@ -96,17 +100,20 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
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.domElement,
event.offsetX,
event.offsetY
);
this.onDownPosition.fromArray(array); 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();
@ -114,50 +121,51 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
//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.onMouseUp = function (event) {
this.domElement.removeEventListener( 'mouseup', on_mouse_up, false ); this.domElement.removeEventListener("mouseup", on_mouse_up, false);
var array = this.getMousePosition(this.domElement, event.offsetX, event.offsetY ); var array = this.getMousePosition(
this.domElement,
event.offsetX,
event.offsetY
);
this.onUpPosition.fromArray(array); this.onUpPosition.fromArray(array);
console.log("mouse up", array); console.log("mouse up", array);
@ -170,8 +178,7 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
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,11 +187,9 @@ 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";
@ -194,8 +199,7 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
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;
} }
@ -203,8 +207,7 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
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;
} }
@ -213,9 +216,7 @@ function Mouse(view, op_state, mainui_container, parentUi, on_left_click, on_rig
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,89 +1,110 @@
// 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",
"Van",
popularCategories = ["Car", "Pedestrian", "Van", "Bus", "Truck", "Scooter", "ScooterRider", "Bicycle", "BicycleRider"]; "Bus",
"Truck",
"Scooter",
"ScooterRider",
"Bicycle",
"BicycleRider",
];
guess_obj_type_by_dimension(scale) { 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;
@ -107,28 +128,29 @@ class ObjectCategory
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,
}; };
} }
@ -136,8 +158,7 @@ class ObjectCategory
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,8 +1,4 @@
class ObjectIdManager {
class ObjectIdManager
{
maxId = 1; maxId = 1;
objectList = []; objectList = [];
//todo: should use all worldlist //todo: should use all worldlist
@ -12,34 +8,45 @@ class ObjectIdManager
} }
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 = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio); renderer.setPixelRatio(window.devicePixelRatio);
camera = new THREE.PerspectiveCamera(
65,
camera = new THREE.PerspectiveCamera( 65, window.innerWidth / window.innerHeight, 1, 800 ); 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); 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) { switch (ev.key) {
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;
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,7 +79,6 @@ function keydown( ev ) {
} }
} }
function onWindowResize() { function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight; camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
@ -98,28 +88,36 @@ 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
@ -143,29 +141,25 @@ function load_pcd(name, file, overall_color){
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 selectionBox = new SelectionBox(camera, scene);
var helper = new SelectionHelper( selectionBox, renderer, 'selectBox' ); var helper = new SelectionHelper(selectionBox, renderer, "selectBox");
document.addEventListener( 'mousedown', function ( event ) { document.addEventListener("mousedown", function (event) {
for (var item of selectionBox.collection) { for (var item of selectionBox.collection) {
item.material.emissive.set(0x000000); 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 ) { document.addEventListener("mousemove", function (event) {
if (helper.isDown) { if (helper.isDown) {
for (var i = 0; i < selectionBox.collection.length; i++) { for (var i = 0; i < selectionBox.collection.length; i++) {
selectionBox.collection[i].material.emissive.set(0x000000); selectionBox.collection[i].material.emissive.set(0x000000);
@ -173,18 +167,20 @@ document.addEventListener( 'mousemove', 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);
} }
} }
}); });
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,8 +1,4 @@
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;
@ -15,7 +11,6 @@ function PlayControl(data){
} }
}; };
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;
@ -41,71 +36,53 @@ function PlayControl(data){
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) { async function play_frame(scene_meta, frame, on_load_world_finished) {
if (!scope.stop_play_flag && !scope.pause_play_flag) if (!scope.stop_play_flag && !scope.pause_play_flag) {
{ var world = await scope.data.getWorld(scene_meta.scene, frame);
var world = await scope.data.getWorld(scene_meta.scene, frame)
if (world.preloaded()) {
if (world.preloaded()) //found, data ready //found, data ready
{ scope.data.activate_world(world, function () {
scope.data.activate_world( //on load finished
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( setTimeout(function () {
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){
@ -124,11 +101,9 @@ function PlayControl(data){
// play_frame(scene_meta, data.world.frameInfo.frame); // play_frame(scene_meta, data.world.frameInfo.frame);
// function play_frame(scene_meta, frame){ // function play_frame(scene_meta, frame){
// load_world(sceneName, frame); // load_world(sceneName, frame);
// if (!stop_play_flag) // if (!stop_play_flag)
// { // {
// var frame_index = scene_meta.frames.findIndex(function(x){return x == frame;}); // var frame_index = scene_meta.frames.findIndex(function(x){return x == frame;});
@ -148,8 +123,6 @@ function PlayControl(data){
// } // }
// }; // };
// } // }
} }
export { PlayControl }; export { PlayControl };

@ -1,22 +1,15 @@
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 };
@ -36,11 +29,10 @@ class MovableView
}); });
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";
@ -50,22 +42,17 @@ class MovableView
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
@ -78,8 +65,7 @@ class PopupDialog extends MovableView
}; };
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();
@ -104,32 +90,25 @@ class PopupDialog extends MovableView
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%";
@ -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";
}; };
} }
@ -152,34 +131,25 @@ class PopupDialog extends MovableView
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,6 +1,6 @@
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;
@ -11,7 +11,8 @@ 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;
@ -25,7 +26,6 @@ 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;
@ -37,15 +37,13 @@ function Radar(sceneMeta, world, frameInfo, radarName){
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
@ -69,8 +67,7 @@ function Radar(sceneMeta, world, frameInfo, radarName){
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 [];
} }
}; };
@ -80,10 +77,9 @@ function Radar(sceneMeta, world, frameInfo, radarName){
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;
}; };
@ -98,19 +94,17 @@ function Radar(sceneMeta, world, frameInfo, radarName){
//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;
@ -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);
@ -163,7 +159,6 @@ function Radar(sceneMeta, world, frameInfo, radarName){
//_self.points_backup = mesh; //_self.points_backup = mesh;
_self._afterPreload(); _self._afterPreload();
}, },
// on progress, // on progress,
@ -200,9 +195,15 @@ function Radar(sceneMeta, world, frameInfo, radarName){
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 },
{ {
@ -211,17 +212,20 @@ function Radar(sceneMeta, world, frameInfo, radarName){
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: 1, y: 1, z: 1 },
{ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 },
"radar", "radar",
this.name); this.name
);
} }
}; };
@ -230,28 +234,31 @@ function Radar(sceneMeta, world, frameInfo, radarName){
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;
@ -268,41 +275,44 @@ function Radar(sceneMeta, world, frameInfo, radarName){
let p = position; let p = position;
let v = velocity; let v = velocity;
var body = [ var body = [p[0], p[1], p[2], v[0], v[1], v[2]];
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({
color: color,
linewidth: 1,
opacity: 1,
transparent: true,
});
var arrow = new THREE.LineSegments(geo, material); 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,
}; };
}; };
@ -322,14 +332,16 @@ function Radar(sceneMeta, world, frameInfo, radarName){
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,11 +349,11 @@ 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));
} }
}; };
} }
@ -353,66 +365,59 @@ function RadarManager(sceneMeta, world, frameInfo){
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 = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio); renderer.setPixelRatio(window.devicePixelRatio);
camera = new THREE.PerspectiveCamera(
65,
camera = new THREE.PerspectiveCamera( 65, window.innerWidth / window.innerHeight, 1, 800 ); 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); document.body.appendChild(container);
container.appendChild(renderer.domElement); container.appendChild(renderer.domElement);
document.addEventListener("keydown", keydown) 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);
@ -84,7 +79,6 @@ function load_all(){
} }
function clearAll() { function clearAll() {
remove(clouds["src"]); remove(clouds["src"]);
remove(clouds["tgt"]); remove(clouds["tgt"]);
remove(clouds["out"]); remove(clouds["out"]);
@ -102,16 +96,14 @@ function clearAll(){
} }
} }
function keydown(ev) { function keydown(ev) {
switch (ev.key) { switch (ev.key) {
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;
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,7 +112,6 @@ function keydown( ev ) {
} }
} }
function onWindowResize() { function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight; camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
@ -146,45 +137,52 @@ function animate() {
} }
} }
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
@ -205,25 +203,19 @@ function load_pcd(name, file, overall_color){
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");

@ -1,12 +1,6 @@
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();
@ -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,32 +40,27 @@ 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();
@ -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.length > 0) {
if (worldList[0].data.cfg.disableLabels) { if (worldList[0].data.cfg.disableLabels) {
console.log("labels not loaded, save action is prohibitted.") 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,20 +1,28 @@
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({
color: 0xffffff,
flatShading: true,
});
for (var i = 0; i < 50; i++) { for (var i = 0; i < 50; i++) {
var mesh = new THREE.Mesh(geometry, material); var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = (Math.random() - 0.5) * 1000; mesh.position.x = (Math.random() - 0.5) * 1000;
@ -39,8 +47,6 @@ function init() {
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;
@ -49,14 +55,12 @@ function init() {
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();
} }

@ -1,4 +1,3 @@
import { import {
DefaultLoadingManager, DefaultLoadingManager,
FileLoader, FileLoader,
@ -6,51 +5,41 @@ import {
} 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,29 +1,22 @@
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");
@ -31,32 +24,29 @@ class Trajectory extends PopupDialog{
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) if (event.ctrlKey) {
{ this.objScale *= 1 + scaleRatio;
this.objScale *= 1 + (scaleRatio); } else {
} let clientLength = Math.min(
else this.svgUi.clientWidth,
{ this.svgUi.clientHeight
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();
@ -75,17 +65,19 @@ class Trajectory extends PopupDialog{
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 };
@ -93,38 +85,34 @@ class Trajectory extends PopupDialog{
} }
}); });
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,9 +133,7 @@ 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) {
@ -157,7 +142,6 @@ class Trajectory extends PopupDialog{
} }
} }
let scaler = this.ui.querySelector("#svg-scaler").children; let scaler = this.ui.querySelector("#svg-scaler").children;
if (scaler.length > 0) { if (scaler.length > 0) {
@ -180,33 +164,29 @@ 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,
@ -214,15 +194,14 @@ class Trajectory extends PopupDialog{
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");
@ -233,8 +212,7 @@ class Trajectory extends PopupDialog{
} }
}; };
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,9 +256,8 @@ 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));
@ -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,4 +1,4 @@
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;
@ -9,18 +9,18 @@ function dotproduct(a, b){
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
for (var r = 0; r < m.length / vl; r++) {
//row of matrix
ret[vi * res_l + r] = 0; ret[vi * res_l + r] = 0;
for (var i = 0; i < vl; i++) { for (var i = 0; i < vl; i++) {
ret[vi * res_l + r] += m[r * vl + i] * x[vi * vl + i]; ret[vi * res_l + r] += m[r * vl + i] * x[vi * vl + i];
@ -31,8 +31,8 @@ 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;
@ -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,8 +122,6 @@ 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;
@ -109,11 +135,15 @@ function xyz_to_psr(vertices){
pos.y /= 8; pos.y /= 8;
pos.z /= 8; pos.z /= 8;
var scale = { var scale = {
x: Math.sqrt((ann[0]-ann[ROW])*(ann[0]-ann[ROW])+(ann[1]-ann[ROW+1])*(ann[1]-ann[ROW+1])), x: Math.sqrt(
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])), (ann[0] - ann[ROW]) * (ann[0] - ann[ROW]) +
(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], z: ann[3 * ROW + 2] - ann[2],
}; };
@ -124,19 +154,20 @@ 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 = []; var ret = [];
for (var i = 0; i < v.length; i++) { for (var i = 0; i < v.length; i++) {
if ((i + 1) % 4 != 0) { if ((i + 1) % 4 != 0) {
@ -148,7 +179,6 @@ function vector4to3(v)
} }
function vector_range(v) { function vector_range(v) {
if (v.length === 0) { if (v.length === 0) {
return null; return null;
} }
@ -172,13 +202,11 @@ 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;
@ -204,12 +232,11 @@ 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;
@ -235,11 +262,9 @@ function array_as_vector_index_range(v, vl, p){
return { return {
min: min, min: min,
max: max, max: max,
} };
} }
function vector3_nomalize(m) { function vector3_nomalize(m) {
var ret = []; var ret = [];
for (var i = 0; i < m.length / 3; i++) { for (var i = 0; i < m.length / 3; i++) {
@ -250,8 +275,6 @@ function vector3_nomalize(m){
return ret; return ret;
} }
function mat(m, s, x, y) { function mat(m, s, x, y) {
return m[x * s + y]; return m[x * s + y];
} }
@ -274,24 +297,42 @@ 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
/* /*
@ -380,48 +464,56 @@ 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) {
@ -429,28 +521,64 @@ var linalg_std = {
// 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);
@ -473,25 +601,17 @@ var linalg_std = {
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
@ -519,94 +639,88 @@ function psr_to_xyz_face_points(p,s,r, minGrid){
// [-x, -y, z], [-x, y, z], //rear-right-top, rear-left-top // [-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) { for (let i = 0; i < cornersAInB.length; i += 3) {
let [x,y,z] = cornersAInB.slice(i, i+3) let [x, y, z] = cornersAInB.slice(i, i + 3);
if ( Math.abs(x) < boxB.scale.x/2 && if (
Math.abs(x) < boxB.scale.x / 2 &&
Math.abs(y) < boxB.scale.y / 2 && Math.abs(y) < boxB.scale.y / 2 &&
Math.abs(z) < boxB.scale.z/2) Math.abs(z) < boxB.scale.z / 2
{ ) {
return true; return true;
} }
} }
return false; return false;
@ -616,20 +730,25 @@ function cornersAinB(boxA,boxB){
// 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,
} };

@ -1,78 +1,105 @@
import * as THREE from './lib/three.module.js'; import * as THREE from "./lib/three.module.js";
import { OrbitControls } from './lib/OrbitControls.js'; import { OrbitControls } from "./lib/OrbitControls.js";
//import { OrthographicTrackballControls } from './lib/OrthographicTrackballControls.js'; //import { OrthographicTrackballControls } from './lib/OrthographicTrackballControls.js';
import { TransformControls } from './lib/TransformControls.js'; import { TransformControls } from "./lib/TransformControls.js";
import {matmul2, euler_angle_to_rotate_matrix} from "./util.js" import { matmul2, euler_angle_to_rotate_matrix } from "./util.js";
function ViewManager(
function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, globalRenderFunc, on_box_changed, cfg){ mainViewContainer,
webglScene,
webglMainScene,
renderer,
globalRenderFunc,
on_box_changed,
cfg
) {
this.mainViewContainer = mainViewContainer; this.mainViewContainer = mainViewContainer;
this.globalRenderFunc = globalRenderFunc; this.globalRenderFunc = globalRenderFunc;
this.webglScene = webglScene; this.webglScene = webglScene;
this.webglMainScene = webglMainScene; this.webglMainScene = webglMainScene;
this.renderer = renderer; this.renderer = renderer;
this.mainView = cfg.disableMainView
this.mainView = cfg.disableMainView?null:create_main_view(webglMainScene, renderer, this.globalRenderFunc, this.mainViewContainer, on_box_changed); ? null
: create_main_view(
webglMainScene,
renderer,
this.globalRenderFunc,
this.mainViewContainer,
on_box_changed
);
this.boxViewList = []; this.boxViewList = [];
this.addBoxView = function (subviewsUi) { this.addBoxView = function (subviewsUi) {
let boxview = new BoxView(subviewsUi, this.mainViewContainer, this.webglScene, this.renderer, this); let boxview = new BoxView(
subviewsUi,
this.mainViewContainer,
this.webglScene,
this.renderer,
this
);
this.boxViewList.push(boxview); this.boxViewList.push(boxview);
return boxview; return boxview;
} };
this.onWindowResize = function () { this.onWindowResize = function () {
if (this.mainView) if (this.mainView) this.mainView.onWindowResize();
this.mainView.onWindowResize();
}; };
this.render = function () { this.render = function () {
console.log("render verything"); console.log("render verything");
if (this.mainView) if (this.mainView) this.mainView.renderAll();
this.mainView.renderAll();
this.boxViewList.forEach(v=>{ this.boxViewList.forEach((v) => {
//if (v.ui.style.display != 'none') //we have pseudo box now. render as commanded. //if (v.ui.style.display != 'none') //we have pseudo box now. render as commanded.
v.render() v.render();
}); });
}; };
this.setColorScheme = function () { this.setColorScheme = function () {
let scheme = document.documentElement.className; let scheme = document.documentElement.className;
if (scheme == "theme-dark") if (scheme == "theme-dark") {
{
this.mainView.backgroundColor = new THREE.Color(0.0, 0.0, 0.0); this.mainView.backgroundColor = new THREE.Color(0.0, 0.0, 0.0);
this.boxViewList.forEach(v=>{ this.boxViewList.forEach((v) => {
v.views[0].backgroundColor = new THREE.Color(0.1, 0.05, 0.05); v.views[0].backgroundColor = new THREE.Color(0.1, 0.05, 0.05);
v.views[1].backgroundColor = new THREE.Color(0.05, 0.1, 0.05); v.views[1].backgroundColor = new THREE.Color(0.05, 0.1, 0.05);
v.views[2].backgroundColor = new THREE.Color(0.05, 0.05, 0.1); v.views[2].backgroundColor = new THREE.Color(0.05, 0.05, 0.1);
}); });
} } else {
else{
this.mainView.backgroundColor = new THREE.Color(1.0, 1.0, 1.0); this.mainView.backgroundColor = new THREE.Color(1.0, 1.0, 1.0);
this.boxViewList.forEach(v=>{ this.boxViewList.forEach((v) => {
v.views[0].backgroundColor = new THREE.Color(0.95, 0.9, 0.9); v.views[0].backgroundColor = new THREE.Color(0.95, 0.9, 0.9);
v.views[1].backgroundColor = new THREE.Color(0.9, 0.95, 0.9); v.views[1].backgroundColor = new THREE.Color(0.9, 0.95, 0.9);
v.views[2].backgroundColor = new THREE.Color(0.9, 0.9, 0.95); v.views[2].backgroundColor = new THREE.Color(0.9, 0.9, 0.95);
}) });
} }
}; };
//this.setColorScheme(); //this.setColorScheme();
// no public funcs below // no public funcs below
function create_main_view(scene, renderer, globalRenderFunc, container, on_box_changed){ function create_main_view(
scene,
renderer,
globalRenderFunc,
container,
on_box_changed
) {
var view = {}; var view = {};
view.backgroundColor= (document.documentElement.className == "theme-dark") ? new THREE.Color( 0.0, 0.0, 0.0 ) : new THREE.Color( 1.0, 1.0, 1.0 ); view.backgroundColor =
document.documentElement.className == "theme-dark"
? new THREE.Color(0.0, 0.0, 0.0)
: new THREE.Color(1.0, 1.0, 1.0);
view.zoom_ratio = 1.0; //useless for mainview view.zoom_ratio = 1.0; //useless for mainview
let camera = new THREE.PerspectiveCamera( 65, container.clientWidth / container.clientHeight, 1, 500 ); let camera = new THREE.PerspectiveCamera(
65,
container.clientWidth / container.clientHeight,
1,
500
);
camera.position.x = 0; camera.position.x = 0;
camera.position.z = 50; camera.position.z = 50;
camera.position.y = 0; camera.position.y = 0;
@ -83,7 +110,12 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
view.camera = camera; view.camera = camera;
// make a blind camera to clean background when batch editing is enabled. // make a blind camera to clean background when batch editing is enabled.
camera = new THREE.PerspectiveCamera( 65, container.clientWidth / container.clientHeight, 1, 500 ); camera = new THREE.PerspectiveCamera(
65,
container.clientWidth / container.clientHeight,
1,
500
);
camera.position.x = -1000; camera.position.x = -1000;
camera.position.z = -1000; camera.position.z = -1000;
camera.position.y = -1000; camera.position.y = -1000;
@ -91,7 +123,6 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
camera.lookAt(0, 0, 0); camera.lookAt(0, 0, 0);
view.blind_camera = camera; view.blind_camera = camera;
view.container = container; view.container = container;
view.renderer = renderer; view.renderer = renderer;
view.scene = scene; view.scene = scene;
@ -103,8 +134,7 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
this.renderWithCamera(this.blind_camera); this.renderWithCamera(this.blind_camera);
}; };
view.dumpPose = function() view.dumpPose = function () {
{
console.log(this.camera.position, this.camera.rotation); console.log(this.camera.position, this.camera.rotation);
}; };
@ -134,12 +164,10 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
if (this.active) { if (this.active) {
//this.switch_camera(false); //this.switch_camera(false);
this.renderWithCamera(this.camera); this.renderWithCamera(this.camera);
} } else {
else
{
this.renderWithCamera(this.blind_camera); this.renderWithCamera(this.blind_camera);
} }
} };
view.clearView = function () { view.clearView = function () {
this.renderWithCamera(this.blind_camera); this.renderWithCamera(this.blind_camera);
@ -154,7 +182,6 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
// update viewport, so the operating lines over these views // update viewport, so the operating lines over these views
// will be updated in time. // will be updated in time.
//console.log(left,bottom, width, height); //console.log(left,bottom, width, height);
this.renderer.setViewport(left, bottom, width, height); this.renderer.setViewport(left, bottom, width, height);
@ -165,20 +192,26 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
this.renderer.render(this.scene, camera); this.renderer.render(this.scene, camera);
}; };
var orbit_perspective = new OrbitControls(
var orbit_perspective = new OrbitControls( view.camera_perspective, view.container ); view.camera_perspective,
view.container
);
orbit_perspective.update(); orbit_perspective.update();
orbit_perspective.addEventListener( 'change', globalRenderFunc ); orbit_perspective.addEventListener("change", globalRenderFunc);
//orbit_perspective.enabled = true; //orbit_perspective.enabled = true;
view.orbit_perspective = orbit_perspective; view.orbit_perspective = orbit_perspective;
var transform_control = new TransformControls(
var transform_control = new TransformControls(view.camera_perspective , view.container ); view.camera_perspective,
view.container
);
transform_control.setSpace("local"); transform_control.setSpace("local");
transform_control.addEventListener( 'change', globalRenderFunc ); transform_control.addEventListener("change", globalRenderFunc);
transform_control.addEventListener( 'objectChange', function(e){on_box_changed(e.target.object);}); transform_control.addEventListener("objectChange", function (e) {
on_box_changed(e.target.object);
});
transform_control.addEventListener( 'dragging-changed', function ( event ) { transform_control.addEventListener("dragging-changed", function (event) {
view.orbit_perspective.enabled = !event.value; view.orbit_perspective.enabled = !event.value;
}); });
transform_control.visible = false; transform_control.visible = false;
@ -186,9 +219,6 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
scene.add(transform_control); scene.add(transform_control);
view.transform_control_perspective = transform_control; view.transform_control_perspective = transform_control;
var width = container.clientWidth; var width = container.clientWidth;
var height = container.clientHeight; var height = container.clientHeight;
var asp = width / height; var asp = width / height;
@ -205,12 +235,10 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
// camera = new THREE.OrthographicCamera(-asp*200, asp*200, 200, -200, -200, 200 ); // camera = new THREE.OrthographicCamera(-asp*200, asp*200, 200, -200, -200, 200 );
// camera.position.z = 50; // camera.position.z = 50;
// var cameraOrthoHelper = new THREE.CameraHelper( camera ); // var cameraOrthoHelper = new THREE.CameraHelper( camera );
// cameraOrthoHelper.visible=true; // cameraOrthoHelper.visible=true;
// scene.add( cameraOrthoHelper ); // scene.add( cameraOrthoHelper );
//view.camera_orth = camera; //view.camera_orth = camera;
// var orbit_orth = new OrbitControls( view.camera_orth, view.container ); // var orbit_orth = new OrbitControls( view.camera_orth, view.container );
@ -238,35 +266,27 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
// transform_control.addEventListener( 'change', globalRenderFunc ); // transform_control.addEventListener( 'change', globalRenderFunc );
// transform_control.addEventListener( 'objectChange', function(e){on_box_changed(e.target.object);} ); // transform_control.addEventListener( 'objectChange', function(e){on_box_changed(e.target.object);} );
// transform_control.addEventListener( 'dragging-changed', function ( event ) { // transform_control.addEventListener( 'dragging-changed', function ( event ) {
// view.orbit_orth.enabled = ! event.value; // view.orbit_orth.enabled = ! event.value;
// } ); // } );
// transform_control.visible = false; // transform_control.visible = false;
// //transform_control.enabled = true; // //transform_control.enabled = true;
// //scene.add( transform_control ); // //scene.add( transform_control );
// view.transform_control_orth = transform_control; // view.transform_control_orth = transform_control;
view.camera = view.camera_perspective; view.camera = view.camera_perspective;
view.orbit = view.orbit_perspective; view.orbit = view.orbit_perspective;
view.transform_control = view.transform_control_perspective; view.transform_control = view.transform_control_perspective;
view.switch_camera = function (birdseye) {
view.switch_camera = function(birdseye) if (!birdseye && this.camera === this.camera_orth) {
{
if (!birdseye && (this.camera === this.camera_orth)){
this.camera = this.camera_perspective; this.camera = this.camera_perspective;
this.orbit_orth.enabled = false; this.orbit_orth.enabled = false;
this.orbit_perspective.enabled = true; this.orbit_perspective.enabled = true;
this.orbit = this.orbit_perspective; this.orbit = this.orbit_perspective;
this.transform_control_perspective.detach(); this.transform_control_perspective.detach();
this.transform_control_orth.detach(); this.transform_control_orth.detach();
@ -275,9 +295,7 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
//this.transform_control_perspective.visible = false; //this.transform_control_perspective.visible = false;
//this.transform_control_orth.visible = false; //this.transform_control_orth.visible = false;
this.transform_control = this.transform_control_perspective; this.transform_control = this.transform_control_perspective;
} } else if (birdseye && this.camera === this.camera_perspective) {
else if (birdseye && (this.camera === this.camera_perspective))
{
this.camera = this.camera_orth; this.camera = this.camera_orth;
this.orbit_orth.enabled = true; this.orbit_orth.enabled = true;
this.orbit_perspective.enabled = false; this.orbit_perspective.enabled = false;
@ -315,8 +333,6 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
}; };
view.onWindowResize = function () { view.onWindowResize = function () {
var asp = container.clientWidth / container.clientHeight; var asp = container.clientWidth / container.clientHeight;
// this.camera_orth.left = -asp*200; // this.camera_orth.left = -asp*200;
// this.camera_orth.right = asp*200; // this.camera_orth.right = asp*200;
@ -327,9 +343,9 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
// this.orbit_orth.handleResize(); // this.orbit_orth.handleResize();
// this.orbit_orth.update(); // this.orbit_orth.update();
this.camera_perspective.aspect = container.clientWidth / container.clientHeight; this.camera_perspective.aspect =
container.clientWidth / container.clientHeight;
this.camera_perspective.updateProjectionMatrix(); this.camera_perspective.updateProjectionMatrix();
}; };
view.reset_birdseye = function () { view.reset_birdseye = function () {
@ -338,10 +354,10 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
view.rotate_birdseye = function () { view.rotate_birdseye = function () {
//this.camera_orth.up.set( 1, 0, 0); //this.camera_orth.up.set( 1, 0, 0);
//this.orbit_orth.update(); //this.orbit_orth.update();
} };
view.detach_control = function () { view.detach_control = function () {
this.transform_control.detach(); this.transform_control.detach();
} };
view.target0 = view.orbit.target.clone(); view.target0 = view.orbit.target.clone();
view.position0 = view.camera.position.clone(); view.position0 = view.camera.position.clone();
@ -352,22 +368,35 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
this.target0.copy(this.orbit.target); this.target0.copy(this.orbit.target);
this.position0.copy(this.camera.position); this.position0.copy(this.camera.position);
this.zoom0 = this.camera.zoom; this.zoom0 = this.camera.zoom;
this.scale0 = {x: highlight_obj_scale.x, y: highlight_obj_scale.y, z: highlight_obj_scale.z}; this.scale0 = {
} x: highlight_obj_scale.x,
y: highlight_obj_scale.y,
z: highlight_obj_scale.z,
};
};
view.restore_relative_orbit_state = function (highlight_obj_scale) { view.restore_relative_orbit_state = function (highlight_obj_scale) {
if (view.scale0) { if (view.scale0) {
// restore last viewpoint // restore last viewpoint
var obj_size = Math.sqrt(view.scale0.x*view.scale0.x + view.scale0.y*view.scale0.y + view.scale0.z*view.scale0.z); var obj_size = Math.sqrt(
var target_obj_size = Math.sqrt(highlight_obj_scale.x*highlight_obj_scale.x + highlight_obj_scale.y*highlight_obj_scale.y + highlight_obj_scale.z*highlight_obj_scale.z); view.scale0.x * view.scale0.x +
view.scale0.y * view.scale0.y +
view.scale0.z * view.scale0.z
);
var target_obj_size = Math.sqrt(
highlight_obj_scale.x * highlight_obj_scale.x +
highlight_obj_scale.y * highlight_obj_scale.y +
highlight_obj_scale.z * highlight_obj_scale.z
);
var ratio = target_obj_size / obj_size; var ratio = target_obj_size / obj_size;
this.camera.position.x =
this.camera.position.x = this.orbit.target.x + (this.position0.x - this.target0.x)*ratio; this.orbit.target.x + (this.position0.x - this.target0.x) * ratio;
this.camera.position.y = this.orbit.target.y + (this.position0.y - this.target0.y)*ratio; this.camera.position.y =
this.camera.position.z = this.orbit.target.z + (this.position0.z - this.target0.z)*ratio; this.orbit.target.y + (this.position0.y - this.target0.y) * ratio;
this.camera.position.z =
this.orbit.target.z + (this.position0.z - this.target0.z) * ratio;
this.camera.zoom = this.zoom0; this.camera.zoom = this.zoom0;
} else { } else {
@ -375,19 +404,17 @@ function ViewManager(mainViewContainer, webglScene, webglMainScene, renderer, gl
this.camera.position.set( this.camera.position.set(
this.orbit.target.x + highlight_obj_scale.x * 3, this.orbit.target.x + highlight_obj_scale.x * 3,
this.orbit.target.y + highlight_obj_scale.y * 3, this.orbit.target.y + highlight_obj_scale.y * 3,
this.orbit.target.z + highlight_obj_scale.z*3); this.orbit.target.z + highlight_obj_scale.z * 3
);
} }
// target is set // target is set
} };
return view; return view;
} }
} }
function BoxView(ui, mainViewContainer, scene, renderer, viewManager) { function BoxView(ui, mainViewContainer, scene, renderer, viewManager) {
this.viewManager = viewManager; this.viewManager = viewManager;
this.mainViewContainer = mainViewContainer; this.mainViewContainer = mainViewContainer;
this.ui = ui; //sub-views this.ui = ui; //sub-views
@ -395,10 +422,9 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
// ui offset // ui offset
return { return {
top: this.ui.offsetTop, top: this.ui.offsetTop,
left: this.ui.offsetLeft left: this.ui.offsetLeft,
} };
}; };
this.defaultBox = { this.defaultBox = {
position: { x: -100, y: -100, z: 0 }, position: { x: -100, y: -100, z: 0 },
@ -409,10 +435,9 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
this.box = this.defaultBox; this.box = this.defaultBox;
this.attachBox = function (box) { this.attachBox = function (box) {
this.box = box; this.box = box;
this.views.forEach(v=>{ this.views.forEach((v) => {
//this.box.world.webglGroup.add(v.camera); //this.box.world.webglGroup.add(v.camera);
//this.box.world.webglGroup.add(v.cameraHelper); //this.box.world.webglGroup.add(v.cameraHelper);
@ -431,8 +456,7 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
this.updateCameraPose(this.box); this.updateCameraPose(this.box);
this.updateCameraRange(this.box); this.updateCameraRange(this.box);
if (!dontRender) if (!dontRender) this.render();
this.render();
}; };
this.updateCameraPose = function (box) { this.updateCameraPose = function (box) {
@ -444,17 +468,15 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
}; };
this.hidden = function () { this.hidden = function () {
return this.ui.style.display == 'none'; return this.ui.style.display == "none";
}; };
this.render = function () { this.render = function () {
if (!this.hidden()) if (!this.hidden()) this.views.forEach((v) => v.render());
this.views.forEach((v)=>v.render()); };
}
var scope = this; var scope = this;
scope.projViewProto = { scope.projViewProto = {
render() { render() {
let vp = this.getViewPort(); let vp = this.getViewPort();
@ -469,14 +491,16 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
getViewPort() { getViewPort() {
return { return {
left: this.placeHolderUi.offsetLeft + scope.baseOffset().left, left: this.placeHolderUi.offsetLeft + scope.baseOffset().left,
bottom : this.container.scrollHeight - (scope.baseOffset().top + this.placeHolderUi.offsetTop + this.placeHolderUi.clientHeight), bottom:
this.container.scrollHeight -
(scope.baseOffset().top +
this.placeHolderUi.offsetTop +
this.placeHolderUi.clientHeight),
width: this.placeHolderUi.clientWidth, width: this.placeHolderUi.clientWidth,
height: this.placeHolderUi.clientHeight, height: this.placeHolderUi.clientHeight,
zoom_ratio: this.zoom_ratio, zoom_ratio: this.zoom_ratio,
} };
}, },
}; };
this.views = [ this.views = [
@ -490,7 +514,10 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
view.name = "topview"; view.name = "topview";
view.zoom_ratio = 1.0; view.zoom_ratio = 1.0;
view.backgroundColor =  (document.documentElement.className == "theme-dark") ? new THREE.Color( 0.1, 0.05, 0.05 ) : new THREE.Color( 0.95, 0.9, 0.9 ); view.backgroundColor =
document.documentElement.className == "theme-dark"
? new THREE.Color(0.1, 0.05, 0.05)
: new THREE.Color(0.95, 0.9, 0.9);
view.container = container; view.container = container;
view.scene = scene; view.scene = scene;
view.renderer = renderer; view.renderer = renderer;
@ -517,7 +544,6 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
view.cameraContainer.name = "topview-camera"; view.cameraContainer.name = "topview-camera";
view.cameraContainer.add(camera); view.cameraContainer.add(camera);
view.updateCameraPose = function (box) { view.updateCameraPose = function (box) {
var p = box.position; var p = box.position;
var r = box.rotation; var r = box.rotation;
@ -528,7 +554,6 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
}; };
view.updateCameraRange = function (box) { view.updateCameraRange = function (box) {
var exp_camera_width, exp_camera_height, exp_camera_clip; var exp_camera_width, exp_camera_height, exp_camera_clip;
//view.width = 0.2;//params["side view width"]; //view.width = 0.2;//params["side view width"];
@ -542,11 +567,9 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
if (exp_camera_width / exp_camera_height > view_width / view_height) { if (exp_camera_width / exp_camera_height > view_width / view_height) {
//increase height //increase height
exp_camera_height = exp_camera_width * view_height/view_width; exp_camera_height = (exp_camera_width * view_height) / view_width;
} } else {
else exp_camera_width = (exp_camera_height * view_width) / view_height;
{
exp_camera_width = exp_camera_height * view_width/view_height;
} }
this.camera.top = exp_camera_height / 2; this.camera.top = exp_camera_height / 2;
@ -568,13 +591,15 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
return view; return view;
} }
function createSideView(scene, renderer, container) { function createSideView(scene, renderer, container) {
let view = Object.create(scope.projViewProto); let view = Object.create(scope.projViewProto);
view.name = "sideview"; view.name = "sideview";
view.zoom_ratio = 1.0; view.zoom_ratio = 1.0;
//view.backgroundColor=new THREE.Color( 0.1, 0.2, 0.1 ); //view.backgroundColor=new THREE.Color( 0.1, 0.2, 0.1 );
view.backgroundColor=(document.documentElement.className == "theme-dark") ? new THREE.Color( 0.05, 0.1, 0.05 ) : new THREE.Color( 0.9, 0.95, 0.9 ); view.backgroundColor =
document.documentElement.className == "theme-dark"
? new THREE.Color(0.05, 0.1, 0.05)
: new THREE.Color(0.9, 0.95, 0.9);
view.container = container; view.container = container;
view.scene = scene; view.scene = scene;
view.renderer = renderer; view.renderer = renderer;
@ -614,7 +639,6 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
//camera.up.set( 0, 1, 0); //camera.up.set( 0, 1, 0);
//camera.lookAt( 0, 0, -3 ); //camera.lookAt( 0, 0, -3 );
// camera should not be changed again? // camera should not be changed again?
view.camera = camera; view.camera = camera;
@ -626,7 +650,6 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
view.cameraContainer.position.y = p.y; view.cameraContainer.position.y = p.y;
view.cameraContainer.position.z = p.z; view.cameraContainer.position.z = p.z;
view.cameraContainer.rotation.x = r.x; view.cameraContainer.rotation.x = r.x;
view.cameraContainer.rotation.y = r.y; view.cameraContainer.rotation.y = r.y;
view.cameraContainer.rotation.z = r.z; view.cameraContainer.rotation.z = r.z;
@ -634,26 +657,20 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
// var trans_matrix = euler_angle_to_rotate_matrix(r, p); // var trans_matrix = euler_angle_to_rotate_matrix(r, p);
// this.camera.position.x= p.x; // this.camera.position.x= p.x;
// this.camera.position.y= p.y; // this.camera.position.y= p.y;
// this.camera.position.z= p.z; // this.camera.position.z= p.z;
// var up = matmul2(trans_matrix, [0, 0, 1, 0], 4); // var up = matmul2(trans_matrix, [0, 0, 1, 0], 4);
// this.camera.up.set( up[0], up[1], up[2]); // this.camera.up.set( up[0], up[1], up[2]);
// var at = matmul2(trans_matrix, [0, 1, 0, 1], 4); // var at = matmul2(trans_matrix, [0, 1, 0, 1], 4);
// this.camera.lookAt( at[0], at[1], at[2] ); // this.camera.lookAt( at[0], at[1], at[2] );
// this.camera.updateProjectionMatrix(); // this.camera.updateProjectionMatrix();
// this.cameraHelper.update(); // this.cameraHelper.update();
}; };
view.updateCameraRange = function (box) { view.updateCameraRange = function (box) {
var exp_camera_width, exp_camera_height, exp_camera_clip; var exp_camera_width, exp_camera_height, exp_camera_clip;
//view.width = 0.2;//params["side view width"]; //view.width = 0.2;//params["side view width"];
@ -668,11 +685,9 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
if (exp_camera_width / exp_camera_height > view_width / view_height) { if (exp_camera_width / exp_camera_height > view_width / view_height) {
//increase height //increase height
exp_camera_height = exp_camera_width * view_height/view_width; exp_camera_height = (exp_camera_width * view_height) / view_width;
} } else {
else exp_camera_width = (exp_camera_height * view_width) / view_height;
{
exp_camera_width = exp_camera_height * view_width/view_height;
} }
this.camera.top = exp_camera_height / 2; this.camera.top = exp_camera_height / 2;
@ -696,7 +711,10 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
view.name = "backview"; view.name = "backview";
view.zoom_ratio = 1.0; view.zoom_ratio = 1.0;
//view.backgroundColor=new THREE.Color( 0.2, 0.1, 0.1 ); //view.backgroundColor=new THREE.Color( 0.2, 0.1, 0.1 );
view.backgroundColor= (document.documentElement.className == "theme-dark") ? new THREE.Color( 0.05, 0.05, 0.1 ) : new THREE.Color( 0.9, 0.9, 0.95 ); view.backgroundColor =
document.documentElement.className == "theme-dark"
? new THREE.Color(0.05, 0.05, 0.1)
: new THREE.Color(0.9, 0.9, 0.95);
view.container = container; view.container = container;
view.scene = scene; view.scene = scene;
view.renderer = renderer; view.renderer = renderer;
@ -727,7 +745,6 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
view.cameraContainer.add(camera); view.cameraContainer.add(camera);
view.updateCameraPose = function (box) { view.updateCameraPose = function (box) {
let p = box.position; let p = box.position;
let r = box.rotation; let r = box.rotation;
@ -742,7 +759,6 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
// var at3 = matmul2(trans_matrix, [1, 0, 0, 1], 4); // var at3 = matmul2(trans_matrix, [1, 0, 0, 1], 4);
// this.camera.lookAt( at3[0], at3[1], at3[2] ); // this.camera.lookAt( at3[0], at3[1], at3[2] );
// this.camera.updateProjectionMatrix(); // this.camera.updateProjectionMatrix();
// this.cameraHelper.update(); // this.cameraHelper.update();
@ -751,7 +767,6 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
}; };
view.updateCameraRange = function (box) { view.updateCameraRange = function (box) {
var exp_camera_width, exp_camera_height, exp_camera_clip; var exp_camera_width, exp_camera_height, exp_camera_clip;
//view.width = 0.2;//params["side view width"]; //view.width = 0.2;//params["side view width"];
@ -765,11 +780,9 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
if (exp_camera_width / exp_camera_height > view_width / view_height) { if (exp_camera_width / exp_camera_height > view_width / view_height) {
//increase height //increase height
exp_camera_height = exp_camera_width * view_height/view_width; exp_camera_height = (exp_camera_width * view_height) / view_width;
} } else {
else exp_camera_width = (exp_camera_height * view_width) / view_height;
{
exp_camera_width = exp_camera_height * view_width/view_height;
} }
this.camera.top = exp_camera_height / 2; this.camera.top = exp_camera_height / 2;
@ -789,4 +802,4 @@ function BoxView(ui, mainViewContainer, scene, renderer, viewManager){
} }
} }
export {ViewManager} export { ViewManager };

@ -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,
matmul,
matmul2,
mat,
} from "./util.js";
function FrameInfo(data, sceneMeta, sceneName, frame) { 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,39 +34,33 @@ 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];
@ -83,12 +80,25 @@ function FrameInfo(data, sceneMeta, sceneName, frame){
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(
_self.transform_matrix,
ps[3 * i + 0],
ps[3 * i + 1],
ps[3 * i + 2]
);
ps[i * 3 + 0] = p[0]; ps[i * 3 + 0] = p[0];
ps[i * 3 + 1] = p[1]; ps[i * 3 + 1] = p[1];
ps[i * 3 + 2] = p[2]; ps[i * 3 + 2] = p[2];
@ -103,8 +113,7 @@ function FrameInfo(data, sceneMeta, sceneName, frame){
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) {
@ -123,8 +132,14 @@ function FrameInfo(data, sceneMeta, sceneName, frame){
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]) +
(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], 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;
@ -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.
@ -195,33 +212,35 @@ function Images(sceneMeta, sceneName, frame){
_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,18 +253,17 @@ 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;
@ -253,12 +271,12 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
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);
} }
@ -269,19 +287,15 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
} }
}; };
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,130 +347,143 @@ 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();
@ -458,21 +492,21 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
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;
@ -480,13 +514,11 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
if (this.preloaded()) { if (this.preloaded()) {
this.go(); this.go();
} }
}; });
this.active = false, (this.active = false), (this.everythingDone = false);
this.everythingDone = false;
this.go = function () { this.go = function () {
if (this.everythingDone) { if (this.everythingDone) {
//console.error("re-activate world?"); //console.error("re-activate world?");
@ -498,7 +530,6 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
} }
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) {
@ -518,10 +549,15 @@ 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) {
@ -532,31 +568,30 @@ 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({
color: color,
linewidth: 1,
opacity: this.data.cfg.box_opacity,
transparent: true,
});
return new THREE.LineSegments(line, material); return new THREE.LineSegments(line, material);
}; };
this.destroyed = false; this.destroyed = false;
// todo, Image resource to be released? // todo, Image resource to be released?
@ -576,8 +611,6 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
} }
}; };
this.deleteAll = function () { this.deleteAll = function () {
var _self = this; var _self = this;
@ -606,4 +639,3 @@ function World(data, sceneName, frame, coordinatesOffset, on_preload_finished){
} }
export { World }; export { World };

Loading…
Cancel
Save