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

main
陈炎群 4 months ago
parent f374f4c12c
commit d4602681c7

File diff suppressed because it is too large Load Diff

@ -1,463 +1,469 @@
import {transpose, matmul2, euler_angle_to_rotate_matrix_3by3,normalizeAngle } from "./util.js";
import {
transpose,
matmul2,
euler_angle_to_rotate_matrix_3by3,
normalizeAngle,
} from "./util.js";
import { logger } from "./log.js";
// todo: this module needs a proper name
function AutoAdjust(boxOp, mouse, header){
this.boxOp = boxOp,
this.mouse = mouse;
this.header = header;
var marked_object = null;
// mark bbox, which will be used as reference-bbox of an object.
this.mark_bbox=function(box){
if (box){
this.marked_object = {
frame: box.world.frameInfo.frame,
scene: box.world.frameInfo.scene,
ann: box.world.annotation.boxToAnn(box),
}
logger.log(`selected reference objcet ${this.marked_object}`);
this.header.set_ref_obj(this.marked_object);
function AutoAdjust(boxOp, mouse, header) {
(this.boxOp = boxOp), (this.mouse = mouse);
this.header = header;
var marked_object = null;
// mark bbox, which will be used as reference-bbox of an object.
this.mark_bbox = function (box) {
if (box) {
this.marked_object = {
frame: box.world.frameInfo.frame,
scene: box.world.frameInfo.scene,
ann: box.world.annotation.boxToAnn(box),
};
logger.log(`selected reference objcet ${this.marked_object}`);
this.header.set_ref_obj(this.marked_object);
}
};
this.followStaticObjects = function (box) {
let world = box.world;
let staticObjects = world.annotation.boxes
.filter((b) => b != box && b.obj_attr && b.obj_attr.search("static") >= 0)
.map((refObj) => {
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
let trans = transpose(coord, 3);
let p = [
box.position.x - refObj.position.x,
box.position.y - refObj.position.y,
box.position.z - refObj.position.z,
];
let relativePos = matmul2(trans, p, 3);
let relativeRot = {
x: normalizeAngle(box.rotation.x - refObj.rotation.x),
y: normalizeAngle(box.rotation.y - refObj.rotation.y),
z: normalizeAngle(box.rotation.z - refObj.rotation.z),
};
let distance = Math.sqrt(
relativePos[0] * relativePos[0] +
relativePos[1] * relativePos[1] +
relativePos[2] * relativePos[2]
);
return {
obj_track_id: refObj.obj_track_id,
relativePos,
relativeRot,
distance,
};
});
let worldList = box.world.data.worldList;
//let saveList = [];
worldList.forEach((w) => {
if (w === box.world) {
//current frame
return;
}
let existedBox = w.annotation.boxes.find(
(b) => b.obj_track_id == box.obj_track_id
);
if (existedBox && !existedBox.annotator) {
// have same objects annotated.
// if its generated by machine, lets overwrite it
return;
}
let candPoseSets = staticObjects.map((refObj) => {
let refObjInW = w.annotation.boxes.find(
(b) => b.obj_track_id == refObj.obj_track_id
);
if (!refObjInW) {
// not found refobj in this world, give up
return null;
}
let relativePos = refObj.relativePos;
let relativeRot = refObj.relativeRot;
let coord = euler_angle_to_rotate_matrix_3by3(refObjInW.rotation);
let rp = matmul2(coord, relativePos, 3);
let newObjPos = {
x: refObjInW.position.x + rp[0],
y: refObjInW.position.y + rp[1],
z: refObjInW.position.z + rp[2],
};
let newObjRot = {
x: normalizeAngle(refObjInW.rotation.x + relativeRot.x),
y: normalizeAngle(refObjInW.rotation.y + relativeRot.y),
z: normalizeAngle(refObjInW.rotation.z + relativeRot.z),
};
return {
distance: refObj.distance,
weight: Math.exp(-refObj.distance * (refObjInW.annotator ? 1 : 0.1)),
position: newObjPos,
rotation: newObjRot,
};
});
candPoseSets = candPoseSets.filter((p) => !!p);
if (candPoseSets.length == 0) {
return;
}
// calculate mean pos/rot
let denorm = candPoseSets.reduce((a, b) => a + b.weight, 0);
let newObjPos = { x: 0, y: 0, z: 0 };
let newObjRot = { x: 0, y: 0, z: 0, cosZ: 0, sinZ: 0 };
candPoseSets.forEach((p) => {
newObjPos.x += p.position.x * p.weight;
newObjPos.y += p.position.y * p.weight;
newObjPos.z += p.position.z * p.weight;
newObjRot.x += p.rotation.x * p.weight;
newObjRot.y += p.rotation.y * p.weight;
//newObjRot.z += p.rotation.z * p.weight;
newObjRot.cosZ += Math.cos(p.rotation.z) * p.weight;
newObjRot.sinZ += Math.sin(p.rotation.z) * p.weight;
});
newObjPos.x /= denorm;
newObjPos.y /= denorm;
newObjPos.z /= denorm;
newObjRot.x /= denorm;
newObjRot.y /= denorm;
newObjRot.cosZ /= denorm;
newObjRot.sinZ /= denorm;
newObjRot.z = Math.atan2(newObjRot.sinZ, newObjRot.cosZ);
// ignor distant objects
if (pointsGlobalConfig.ignoreDistantObject) {
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) {
return;
}
};
this.followStaticObjects = function(box) {
let world = box.world;
let staticObjects = world.annotation.boxes.
filter(b=>b!=box && b.obj_attr && b.obj_attr.search('static')>=0).
map(refObj=>{
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
let trans = transpose(coord, 3);
let p = [box.position.x - refObj.position.x,
box.position.y - refObj.position.y,
box.position.z - refObj.position.z];
let relativePos = matmul2(trans, p, 3);
let relativeRot = {
x: normalizeAngle(box.rotation.x - refObj.rotation.x),
y: normalizeAngle(box.rotation.y - refObj.rotation.y),
z: normalizeAngle(box.rotation.z - refObj.rotation.z),
};
let distance = Math.sqrt(relativePos[0]*relativePos[0] + relativePos[1]*relativePos[1] + relativePos[2]*relativePos[2]);
return {
obj_track_id: refObj.obj_track_id,
relativePos,
relativeRot,
distance
}
});
let worldList = box.world.data.worldList;
//let saveList = [];
worldList.forEach(w=>{
if (w === box.world){
//current frame
return;
}
let existedBox = w.annotation.boxes.find(b=>b.obj_track_id == box.obj_track_id);
if (existedBox && !existedBox.annotator)
{
// have same objects annotated.
// if its generated by machine, lets overwrite it
return;
}
let candPoseSets = staticObjects.map(refObj=>{
let refObjInW = w.annotation.boxes.find(b=>b.obj_track_id == refObj.obj_track_id);
if (!refObjInW){
// not found refobj in this world, give up
return null;
}
let relativePos = refObj.relativePos;
let relativeRot = refObj.relativeRot;
let coord = euler_angle_to_rotate_matrix_3by3(refObjInW.rotation);
let rp = matmul2(coord, relativePos, 3);
let newObjPos = {
x: refObjInW.position.x + rp[0],
y: refObjInW.position.y + rp[1],
z: refObjInW.position.z + rp[2],
};
let newObjRot = {
x: normalizeAngle(refObjInW.rotation.x + relativeRot.x),
y: normalizeAngle(refObjInW.rotation.y + relativeRot.y),
z: normalizeAngle(refObjInW.rotation.z + relativeRot.z)
};
return {
distance: refObj.distance,
weight: Math.exp(-refObj.distance * (refObjInW.annotator?1:0.1)),
position: newObjPos,
rotation: newObjRot,
};
});
candPoseSets = candPoseSets.filter(p=>!!p);
if (candPoseSets.length == 0) {
return;
}
// calculate mean pos/rot
let denorm = candPoseSets.reduce((a,b)=>a+b.weight, 0);
let newObjPos = {x:0, y:0, z:0};
let newObjRot = {x:0, y:0, z:0, cosZ: 0, sinZ:0};
candPoseSets.forEach(p=>{
newObjPos.x += p.position.x * p.weight;
newObjPos.y += p.position.y * p.weight;
newObjPos.z += p.position.z * p.weight;
newObjRot.x += p.rotation.x * p.weight;
newObjRot.y += p.rotation.y * p.weight;
//newObjRot.z += p.rotation.z * p.weight;
newObjRot.cosZ += Math.cos(p.rotation.z) * p.weight;
newObjRot.sinZ += Math.sin(p.rotation.z) * p.weight;
});
newObjPos.x /= denorm;
newObjPos.y /= denorm;
newObjPos.z /= denorm;
newObjRot.x /= denorm;
newObjRot.y /= denorm;
newObjRot.cosZ /= denorm;
newObjRot.sinZ /= denorm;
newObjRot.z = Math.atan2(newObjRot.sinZ, newObjRot.cosZ);
// ignor distant objects
if (pointsGlobalConfig.ignoreDistantObject){
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)
{
return;
}
}
// apply
if (existedBox){
existedBox.position.x = newObjPos.x;
existedBox.position.y = newObjPos.y;
existedBox.position.z = newObjPos.z;
existedBox.rotation.x = newObjRot.x;
existedBox.rotation.y = newObjRot.y;
existedBox.rotation.z = newObjRot.z;
existedBox.scale.x = box.scale.x;
existedBox.scale.y = box.scale.y;
existedBox.scale.z = box.scale.z;
existedBox.annotator="S";
logger.log(`modified box in ${w}`);
} else{
let newBox = w.annotation.add_box(newObjPos,
box.scale,
newObjRot,
box.obj_type,
box.obj_track_id,
box.obj_attr);
newBox.annotator="S";
w.annotation.load_box(newBox);
logger.log(`inserted box in ${w}`);
}
console.log("added box in ", w.frameInfo.frame);
//saveList.push(w);
w.annotation.setModified();
});
};
this.followsRef = function(box){
//find ref object in current frame
let world = box.world;
let refObj = world.annotation.boxes.find(b=>b.obj_track_id == this.marked_object.ann.obj_id);
if (refObj){
console.log("found ref obj in current frame");
world.annotation.setModified()
//compute relative position
// represent obj in coordinate system of refobj
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
let trans = transpose(coord, 3);
let p = [box.position.x - refObj.position.x,
box.position.y - refObj.position.y,
box.position.z - refObj.position.z];
const relativePos = matmul2(trans, p, 3);
const relativeRot = {
x: box.rotation.x - refObj.rotation.x,
y: box.rotation.y - refObj.rotation.y,
z: box.rotation.z - refObj.rotation.z,
};
let worldList = box.world.data.worldList;
//let saveList = [];
worldList.forEach(w=>{
if (w === box.world){
//current frame
return;
}
let existedBox = w.annotation.boxes.find(b=>b.obj_track_id == box.obj_track_id);
if (existedBox && !existedBox.annotator)
{
// have same objects annotated.
// if its generated by machine, lets overwrite it
return;
}
let refObjInW = w.annotation.boxes.find(b=>b.obj_track_id == refObj.obj_track_id);
if (!refObjInW){
// not found refobj in this world, give up
return;
}
let coord = euler_angle_to_rotate_matrix_3by3(refObjInW.rotation);
let rp = matmul2(coord, relativePos, 3);
let newObjPos = {
x: refObjInW.position.x + rp[0],
y: refObjInW.position.y + rp[1],
z: refObjInW.position.z + rp[2],
};
let newObjRot = {
x: refObjInW.rotation.x + relativeRot.x,
y: refObjInW.rotation.y + relativeRot.y,
z: refObjInW.rotation.z + relativeRot.z
};
if (existedBox){
existedBox.position.x = newObjPos.x;
existedBox.position.y = newObjPos.y;
existedBox.position.z = newObjPos.z;
existedBox.rotation.x = newObjRot.x;
existedBox.rotation.y = newObjRot.y;
existedBox.rotation.z = newObjRot.z;
existedBox.scale.x = box.scale.x;
existedBox.scale.y = box.scale.y;
existedBox.scale.z = box.scale.z;
existedBox.annotator="F";
existedBox.follows = {
obj_track_id: refObj.obj_track_id,
relative_position: {
x: relativePos[0],
y: relativePos[1],
z: relativePos[2],
},
relative_rotation: relativeRot,
};
logger.log(`modified box in ${w}`);
} else{
let newBox = w.annotation.add_box(newObjPos,
box.scale,
newObjRot,
box.obj_type,
box.obj_track_id,
box.obj_attr);
newBox.annotator="F";
newBox.follows = {
obj_track_id: refObj.obj_track_id,
relative_position: {
x: relativePos[0],
y: relativePos[1],
z: relativePos[2],
},
relative_rotation: relativeRot,
};
w.annotation.load_box(newBox);
logger.log(`inserted box in ${w}`);
}
console.log("added box in ", w.frameInfo.frame);
//saveList.push(w);
w.annotation.setModified();
});
//saveWorldList(saveList);
}
// apply
if (existedBox) {
existedBox.position.x = newObjPos.x;
existedBox.position.y = newObjPos.y;
existedBox.position.z = newObjPos.z;
existedBox.rotation.x = newObjRot.x;
existedBox.rotation.y = newObjRot.y;
existedBox.rotation.z = newObjRot.z;
existedBox.scale.x = box.scale.x;
existedBox.scale.y = box.scale.y;
existedBox.scale.z = box.scale.z;
existedBox.annotator = "S";
logger.log(`modified box in ${w}`);
} else {
let newBox = w.annotation.add_box(
newObjPos,
box.scale,
newObjRot,
box.obj_type,
box.obj_track_id,
box.obj_attr
);
newBox.annotator = "S";
w.annotation.load_box(newBox);
logger.log(`inserted box in ${w}`);
}
console.log("added box in ", w.frameInfo.frame);
//saveList.push(w);
w.annotation.setModified();
});
};
this.followsRef = function (box) {
//find ref object in current frame
let world = box.world;
let refObj = world.annotation.boxes.find(
(b) => b.obj_track_id == this.marked_object.ann.obj_id
);
if (refObj) {
console.log("found ref obj in current frame");
world.annotation.setModified();
//compute relative position
// represent obj in coordinate system of refobj
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
let trans = transpose(coord, 3);
let p = [
box.position.x - refObj.position.x,
box.position.y - refObj.position.y,
box.position.z - refObj.position.z,
];
const relativePos = matmul2(trans, p, 3);
const relativeRot = {
x: box.rotation.x - refObj.rotation.x,
y: box.rotation.y - refObj.rotation.y,
z: box.rotation.z - refObj.rotation.z,
};
let worldList = box.world.data.worldList;
//let saveList = [];
worldList.forEach((w) => {
if (w === box.world) {
//current frame
return;
}
};
this.syncFollowers = function(box){
let world = box.world;
let allFollowers = world.annotation.boxes.filter(b=>b.follows && b.follows.obj_track_id === box.obj_track_id);
let existedBox = w.annotation.boxes.find(
(b) => b.obj_track_id == box.obj_track_id
);
if (allFollowers.length == 0){
console.log("no followers");
return;
if (existedBox && !existedBox.annotator) {
// have same objects annotated.
// if its generated by machine, lets overwrite it
return;
}
let refObj = box;
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
allFollowers.forEach(fb=>{
let relpos = [fb.follows.relative_position.x,
fb.follows.relative_position.y,
fb.follows.relative_position.z,
];
let rp = matmul2(coord, relpos, 3);
fb.position.x = refObj.position.x + rp[0];
fb.position.y = refObj.position.y + rp[1];
fb.position.z = refObj.position.z + rp[2];
fb.rotation.x = refObj.rotation.x + fb.follows.relative_rotation.x;
fb.rotation.y = refObj.rotation.y + fb.follows.relative_rotation.y;
fb.rotation.z = refObj.rotation.z + fb.follows.relative_rotation.z;
});
};
this.paste_bbox=function(pos, add_box){
if (!pos)
pos = this.marked_object.ann.psr.position;
else
pos.z = this.marked_object.ann.psr.position.z;
return add_box(pos, this.marked_object.ann.psr.scale, 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.auto_adjust_bbox=function(box, done, on_box_changed){
// saveWorld(function(){
// do_adjust(box, on_box_changed);
// });
// let _self =this;
// function do_adjust(box, on_box_changed){
// console.log("auto adjust highlighted bbox");
// var xhr = new XMLHttpRequest();
// // we defined the xhr
// xhr.onreadystatechange = function () {
// if (this.readyState != 4) return;
// if (this.status == 200) {
// console.log(this.responseText)
// console.log(box.position);
// console.log(box.rotation);
// var trans_mat = JSON.parse(this.responseText);
// var rotation = Math.atan2(trans_mat[4], trans_mat[0]) + box.rotation.z;
// var transform = {
// x: -trans_mat[3],
// y: -trans_mat[7],
// z: -trans_mat[11],
// }
// /*
// cos sin x
// -sin cos y
// */
// var new_pos = {
// x: Math.cos(-rotation) * transform.x + Math.sin(-rotation) * transform.y,
// y: -Math.sin(-rotation) * transform.x + Math.cos(-rotation) * transform.y,
// z: transform.z,
// };
// box.position.x += new_pos.x;
// box.position.y += new_pos.y;
// box.position.z += new_pos.z;
// box.scale.x = marked_object.scale.x;
// box.scale.y = marked_object.scale.y;
// box.scale.z = marked_object.scale.z;
// box.rotation.z -= Math.atan2(trans_mat[4], trans_mat[0]);
// console.log(box.position);
// console.log(box.rotation);
// on_box_changed(box);
// _self.header.mark_changed_flag();
// if (done){
// done();
// }
// }
// // end of state change: it can be after some time (async)
// };
// xhr.open('GET',
// "/auto_adjust"+"?scene="+marked_object.scene + "&"+
// "ref_frame=" + marked_object.frame + "&" +
// "object_id=" + marked_object.obj_track_id + "&" +
// "adj_frame=" + data.world.frameInfo.frame,
// true);
// xhr.send();
// }
// };
this.smart_paste=function(selected_box, add_box, on_box_changed){
var box = selected_box;
if (!box){
let sceneP = this.mouse.get_mouse_location_in_world()
// trans pos to world local pos
//let pos = this.data.world.scenePosToLidar(sceneP);
box = this.paste_bbox(pos, add_box);
let refObjInW = w.annotation.boxes.find(
(b) => b.obj_track_id == refObj.obj_track_id
);
if (!refObjInW) {
// not found refobj in this world, give up
return;
}
else if (this.marked_object){
box.scale.x = this.marked_object.ann.psr.scale.x;
box.scale.y = this.marked_object.ann.psr.scale.y;
box.scale.z = this.marked_object.ann.psr.scale.z;
let coord = euler_angle_to_rotate_matrix_3by3(refObjInW.rotation);
let rp = matmul2(coord, relativePos, 3);
let newObjPos = {
x: refObjInW.position.x + rp[0],
y: refObjInW.position.y + rp[1],
z: refObjInW.position.z + rp[2],
};
let newObjRot = {
x: refObjInW.rotation.x + relativeRot.x,
y: refObjInW.rotation.y + relativeRot.y,
z: refObjInW.rotation.z + relativeRot.z,
};
if (existedBox) {
existedBox.position.x = newObjPos.x;
existedBox.position.y = newObjPos.y;
existedBox.position.z = newObjPos.z;
existedBox.rotation.x = newObjRot.x;
existedBox.rotation.y = newObjRot.y;
existedBox.rotation.z = newObjRot.z;
existedBox.scale.x = box.scale.x;
existedBox.scale.y = box.scale.y;
existedBox.scale.z = box.scale.z;
existedBox.annotator = "F";
existedBox.follows = {
obj_track_id: refObj.obj_track_id,
relative_position: {
x: relativePos[0],
y: relativePos[1],
z: relativePos[2],
},
relative_rotation: relativeRot,
};
logger.log(`modified box in ${w}`);
} else {
let newBox = w.annotation.add_box(
newObjPos,
box.scale,
newObjRot,
box.obj_type,
box.obj_track_id,
box.obj_attr
);
newBox.annotator = "F";
newBox.follows = {
obj_track_id: refObj.obj_track_id,
relative_position: {
x: relativePos[0],
y: relativePos[1],
z: relativePos[2],
},
relative_rotation: relativeRot,
};
w.annotation.load_box(newBox);
logger.log(`inserted box in ${w}`);
}
// this.auto_adjust_bbox(box,
// function(){saveWorld();},
// on_box_changed);
// this.header.mark_changed_flag();
this.boxOp.auto_rotate_xyz(box, null, null,
on_box_changed,
"noscaling");
};
}
console.log("added box in ", w.frameInfo.frame);
//saveList.push(w);
w.annotation.setModified();
});
//saveWorldList(saveList);
}
};
this.syncFollowers = function (box) {
let world = box.world;
let allFollowers = world.annotation.boxes.filter(
(b) => b.follows && b.follows.obj_track_id === box.obj_track_id
);
if (allFollowers.length == 0) {
console.log("no followers");
return;
}
let refObj = box;
let coord = euler_angle_to_rotate_matrix_3by3(refObj.rotation);
allFollowers.forEach((fb) => {
let relpos = [
fb.follows.relative_position.x,
fb.follows.relative_position.y,
fb.follows.relative_position.z,
];
let rp = matmul2(coord, relpos, 3);
fb.position.x = refObj.position.x + rp[0];
fb.position.y = refObj.position.y + rp[1];
fb.position.z = refObj.position.z + rp[2];
fb.rotation.x = refObj.rotation.x + fb.follows.relative_rotation.x;
fb.rotation.y = refObj.rotation.y + fb.follows.relative_rotation.y;
fb.rotation.z = refObj.rotation.z + fb.follows.relative_rotation.z;
});
};
this.paste_bbox = function (pos, add_box) {
if (!pos) pos = this.marked_object.ann.psr.position;
else pos.z = this.marked_object.ann.psr.position.z;
return add_box(
pos,
this.marked_object.ann.psr.scale,
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.auto_adjust_bbox=function(box, done, on_box_changed){
// saveWorld(function(){
// do_adjust(box, on_box_changed);
// });
// let _self =this;
// function do_adjust(box, on_box_changed){
// console.log("auto adjust highlighted bbox");
// var xhr = new XMLHttpRequest();
// // we defined the xhr
// xhr.onreadystatechange = function () {
// if (this.readyState != 4) return;
// if (this.status == 200) {
// console.log(this.responseText)
// console.log(box.position);
// console.log(box.rotation);
// var trans_mat = JSON.parse(this.responseText);
// var rotation = Math.atan2(trans_mat[4], trans_mat[0]) + box.rotation.z;
// var transform = {
// x: -trans_mat[3],
// y: -trans_mat[7],
// z: -trans_mat[11],
// }
// /*
// cos sin x
// -sin cos y
// */
// var new_pos = {
// x: Math.cos(-rotation) * transform.x + Math.sin(-rotation) * transform.y,
// y: -Math.sin(-rotation) * transform.x + Math.cos(-rotation) * transform.y,
// z: transform.z,
// };
// box.position.x += new_pos.x;
// box.position.y += new_pos.y;
// box.position.z += new_pos.z;
// box.scale.x = marked_object.scale.x;
// box.scale.y = marked_object.scale.y;
// box.scale.z = marked_object.scale.z;
// box.rotation.z -= Math.atan2(trans_mat[4], trans_mat[0]);
// console.log(box.position);
// console.log(box.rotation);
// on_box_changed(box);
// _self.header.mark_changed_flag();
// if (done){
// done();
// }
// }
// // end of state change: it can be after some time (async)
// };
// xhr.open('GET',
// "/auto_adjust"+"?scene="+marked_object.scene + "&"+
// "ref_frame=" + marked_object.frame + "&" +
// "object_id=" + marked_object.obj_track_id + "&" +
// "adj_frame=" + data.world.frameInfo.frame,
// true);
// xhr.send();
// }
// };
this.smart_paste = function (selected_box, add_box, on_box_changed) {
var box = selected_box;
if (!box) {
let sceneP = this.mouse.get_mouse_location_in_world();
// trans pos to world local pos
//let pos = this.data.world.scenePosToLidar(sceneP);
box = this.paste_bbox(pos, add_box);
} else if (this.marked_object) {
box.scale.x = this.marked_object.ann.psr.scale.x;
box.scale.y = this.marked_object.ann.psr.scale.y;
box.scale.z = this.marked_object.ann.psr.scale.z;
}
// this.auto_adjust_bbox(box,
// function(){saveWorld();},
// on_box_changed);
// this.header.mark_changed_flag();
this.boxOp.auto_rotate_xyz(box, null, null, on_box_changed, "noscaling");
};
}
export {AutoAdjust}
export { AutoAdjust };

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

@ -1,403 +1,387 @@
import * as THREE from './lib/three.module.js';
import { PCDLoader } from './lib/PCDLoader.js';
import { matmul, euler_angle_to_rotate_matrix_3by3} from "./util.js"
import * as THREE from "./lib/three.module.js";
import { PCDLoader } from "./lib/PCDLoader.js";
import { matmul, euler_angle_to_rotate_matrix_3by3 } from "./util.js";
//todo: clean arrows
function AuxLidar(sceneMeta, world, frameInfo, auxLidarName){
this.world = world;
this.frameInfo = frameInfo;
this.name = auxLidarName;
this.sceneMeta = sceneMeta;
this.coordinatesOffset = world.coordinatesOffset;
this.showPointsOnly = true;
this.showCalibBox = false;
//this.cssStyleSelector = this.sceneMeta.calib.aux_lidar[this.name].cssstyleselector;
this.color = this.sceneMeta.calib.aux_lidar[this.name].color;
function AuxLidar(sceneMeta, world, frameInfo, auxLidarName) {
this.world = world;
this.frameInfo = frameInfo;
this.name = auxLidarName;
this.sceneMeta = sceneMeta;
this.coordinatesOffset = world.coordinatesOffset;
this.showPointsOnly = true;
this.showCalibBox = false;
//this.cssStyleSelector = this.sceneMeta.calib.aux_lidar[this.name].cssstyleselector;
this.color = this.sceneMeta.calib.aux_lidar[this.name].color;
if (!this.color) {
this.color = [
this.world.data.cfg.point_brightness,
this.world.data.cfg.point_brightness,
this.world.data.cfg.point_brightness,
];
}
this.lidar_points = null; // read from file, centered at 0
this.elements = null; // geometry points
this.preloaded = false;
this.loaded = false;
this.go_cmd_received = false;
this.webglScene = null;
this.on_go_finished = null;
this.go = function (webglScene, on_go_finished) {
this.webglScene = webglScene;
if (this.preloaded) {
if (this.elements) {
this.webglScene.add(this.elements.points);
if (this.showCalibBox) this.webglScene.add(this.calib_box);
}
this.loaded = true;
if (on_go_finished) on_go_finished();
}
if (!this.color)
//anyway we save go cmd
{
this.color = [
this.world.data.cfg.point_brightness,
this.world.data.cfg.point_brightness,
this.world.data.cfg.point_brightness,
];
this.go_cmd_received = true;
this.on_go_finished = on_go_finished;
}
};
this.lidar_points = null; // read from file, centered at 0
this.elements = null; // geometry points
this.preloaded = false;
this.loaded = false;
this.showCalibBox = function () {
this.showCalibBox = true;
this.webglScene.add(this.calib_box);
};
this.hideCalibBox = function () {
this.showCalibBox = false;
this.webglScene.remove(this.calib_box);
};
this.get_unoffset_lidar_points = function () {
if (this.elements) {
let pts = this.elements.points.geometry.getAttribute("position").array;
return pts.map((p, i) => p - this.world.coordinatesOffset[i % 3]);
} else {
return [];
}
};
this.go_cmd_received = false;
this.webglScene = null;
this.on_go_finished = null;
this.go = function(webglScene, on_go_finished){
this.webglScene = webglScene;
if (this.preloaded){
if (this.elements){
this.webglScene.add(this.elements.points);
if (this.showCalibBox)
this.webglScene.add(this.calib_box);
}
this.loaded = true;
if (on_go_finished)
on_go_finished();
}
//anyway we save go cmd
{
this.go_cmd_received = true;
this.on_go_finished = on_go_finished;
}
};
// todo: what if it's not preloaded yet
this.unload = function (keep_box) {
if (this.elements) {
this.webglScene.remove(this.elements.points);
if (!this.showPointsOnly)
this.elements.arrows.forEach((a) => this.webglScene.remove(a));
this.showCalibBox = function(){
this.showCalibBox = true;
this.webglScene.add(this.calib_box);
};
if (!keep_box) this.webglScene.remove(this.calib_box);
}
this.loaded = false;
};
this.hideCalibBox = function(){
this.showCalibBox = false;
this.webglScene.remove(this.calib_box);
};
// todo: its possible to remove points before preloading,
this.deleteAll = function (keep_box) {
if (this.loaded) {
this.unload();
}
this.get_unoffset_lidar_points = function(){
if (this.elements){
let pts = this.elements.points.geometry.getAttribute("position").array;
return pts.map((p,i)=>p-this.world.coordinatesOffset[i %3]);
}
else{
return [];
}
};
if (this.elements) {
//this.scene.remove(this.points);
this.world.data.dbg.free();
// todo: what if it's not preloaded yet
this.unload = function(keep_box){
if (this.elements){
this.webglScene.remove(this.elements.points);
if (!this.showPointsOnly)
this.elements.arrows.forEach(a=>this.webglScene.remove(a));
if (!keep_box)
this.webglScene.remove(this.calib_box);
}
this.loaded = false;
};
if (this.elements.points) {
this.elements.points.geometry.dispose();
this.elements.points.material.dispose();
}
// todo: its possible to remove points before preloading,
this.deleteAll = function(keep_box){
if (this.loaded){
this.unload();
}
if (this.elements.arrows) {
this.elements.arrows.forEach((a) => {
this.world.data.dbg.free();
a.geometry.dispose();
a.material.dispose();
});
}
if (this.elements){
//this.scene.remove(this.points);
this.world.data.dbg.free();
if (this.elements.points)
{
this.elements.points.geometry.dispose();
this.elements.points.material.dispose();
}
if (this.elements.arrows)
{
this.elements.arrows.forEach(a=>{
this.world.data.dbg.free();
a.geometry.dispose();
a.material.dispose();
})
}
this.elements = null;
}
this.elements = null;
}
if (!keep_box && this.calib_box){
this.world.data.dbg.free();
this.calib_box.geometry.dispose();
this.calib_box.material.dispose();
this.calib_box = null;
}
};
if (!keep_box && this.calib_box) {
this.world.data.dbg.free();
this.calib_box.geometry.dispose();
this.calib_box.material.dispose();
this.calib_box = null;
}
};
this.filterPoints = function(position){
let filtered_position = [];
this.filterPoints = function (position) {
let filtered_position = [];
if (pointsGlobalConfig.enableFilterPoints)
{
for(let i = 0; i <= position.length; i+=3)
{
if (position[i+2] <= pointsGlobalConfig.filterPointsZ)
{
filtered_position.push(position[i]);
filtered_position.push(position[i+1]);
filtered_position.push(position[i+2]);
}
}
if (pointsGlobalConfig.enableFilterPoints) {
for (let i = 0; i <= position.length; i += 3) {
if (position[i + 2] <= pointsGlobalConfig.filterPointsZ) {
filtered_position.push(position[i]);
filtered_position.push(position[i + 1]);
filtered_position.push(position[i + 2]);
}
}
}
return filtered_position;
};
return filtered_position;
};
this.preload = function(on_preload_finished){
this.on_preload_finished = on_preload_finished;
var loader = new PCDLoader();
var _self = this;
loader.load( this.frameInfo.get_aux_lidar_path(this.name),
//ok
function ( pcd ) {
var position = pcd.position;
//_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");
_self.lidar_points = position;
// add one box to calibrate lidar with lidar
_self.calib_box = _self.createCalibBox();
// install callback for box changing
_self.calib_box.on_box_changed = ()=>{
_self.move_lidar(_self.calib_box);
};
//position = _self.transformPointsByOffset(position);
position = _self.move_points(_self.calib_box);
let elements = _self.buildGeometry(position);
_self.elements = elements;
//_self.points_backup = mesh;
_self._afterPreload();
},
// on progress,
function(){},
// on error
function(){
//error
console.log("load lidar failed.");
_self._afterPreload();
},
// on file loaded
function(){
//_self.points_readfile_time = new Date().getTime();
//console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "read file ", _self.points_readfile_time - _self.create_time, "ms");
}
);
};
this.preload = function (on_preload_finished) {
this.on_preload_finished = on_preload_finished;
// internal funcs below
this._afterPreload = function(){
this.preloaded = true;
console.log(`lidar ${this.auxLidarName} preloaded`);
if (this.on_preload_finished){
this.on_preload_finished();
}
if (this.go_cmd_received){
this.go(this.webglScene, this.on_go_finished);
}
};
var loader = new PCDLoader();
this.createCalibBox = function(){
if (this.sceneMeta.calib.aux_lidar && this.sceneMeta.calib.aux_lidar[this.name]){
return this.world.annotation.createCuboid(
{
x: this.sceneMeta.calib.aux_lidar[this.name].translation[0] + 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: this.sceneMeta.calib.aux_lidar[this.name].rotation[0],
y: this.sceneMeta.calib.aux_lidar[this.name].rotation[1],
z: this.sceneMeta.calib.aux_lidar[this.name].rotation[2],
},
"lidar",
this.name);
}else {
return this.world.annotation.createCuboid(
{x: this.coordinatesOffset[0],
y: this.coordinatesOffset[1],
z: this.coordinatesOffset[2]},
{x:0.5, y:0.5, z:0.5},
{x:0,y:0,z:0},
"lidar",
this.name);
}
};
var _self = this;
loader.load(
this.frameInfo.get_aux_lidar_path(this.name),
//ok
function (pcd) {
var position = pcd.position;
this.buildPoints = function(position){
// build geometry
this.world.data.dbg.alloc();
let geometry = new THREE.BufferGeometry();
if ( position.length > 0 )
geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) );
let pointColor = this.color;
let color=[];
for (var i =0; i< position.length; i+=3){
color.push(pointColor[0]);
color.push(pointColor[1]);
color.push(pointColor[2]);
}
//_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");
_self.lidar_points = position;
geometry.addAttribute( 'color', new THREE.Float32BufferAttribute(color, 3 ) );
// add one box to calibrate lidar with lidar
_self.calib_box = _self.createCalibBox();
geometry.computeBoundingSphere();
// build material
let pointSize = this.sceneMeta.calib.aux_lidar[this.name].point_size;
if (!pointSize)
pointSize = 1;
let material = new THREE.PointsMaterial( { size: pointSize, vertexColors: THREE.VertexColors } );
//material.size = 2;
material.sizeAttenuation = false;
// install callback for box changing
_self.calib_box.on_box_changed = () => {
_self.move_lidar(_self.calib_box);
};
// build mesh
let mesh = new THREE.Points( geometry, material );
mesh.name = "lidar";
//position = _self.transformPointsByOffset(position);
position = _self.move_points(_self.calib_box);
return mesh;
};
let elements = _self.buildGeometry(position);
_self.elements = elements;
//_self.points_backup = mesh;
this.buildGeometry = function(position){
let points = this.buildPoints(position);
return {
points: points,
};
};
_self._afterPreload();
},
// on progress,
function () {},
// on error
function () {
//error
console.log("load lidar failed.");
_self._afterPreload();
},
// on file loaded
function () {
//_self.points_readfile_time = new Date().getTime();
//console.log(_self.points_load_time, _self.frameInfo.scene, _self.frameInfo.frame, "read file ", _self.points_readfile_time - _self.create_time, "ms");
}
);
};
// internal funcs below
this._afterPreload = function () {
this.preloaded = true;
console.log(`lidar ${this.auxLidarName} preloaded`);
if (this.on_preload_finished) {
this.on_preload_finished();
}
if (this.go_cmd_received) {
this.go(this.webglScene, this.on_go_finished);
}
};
this.createCalibBox = function () {
if (
this.sceneMeta.calib.aux_lidar &&
this.sceneMeta.calib.aux_lidar[this.name]
) {
return this.world.annotation.createCuboid(
{
x:
this.sceneMeta.calib.aux_lidar[this.name].translation[0] +
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: this.sceneMeta.calib.aux_lidar[this.name].rotation[0],
y: this.sceneMeta.calib.aux_lidar[this.name].rotation[1],
z: this.sceneMeta.calib.aux_lidar[this.name].rotation[2],
},
"lidar",
this.name
);
} else {
return this.world.annotation.createCuboid(
{
x: this.coordinatesOffset[0],
y: this.coordinatesOffset[1],
z: this.coordinatesOffset[2],
},
{ x: 0.5, y: 0.5, z: 0.5 },
{ x: 0, y: 0, z: 0 },
"lidar",
this.name
);
}
};
this.buildPoints = function (position) {
// build geometry
this.world.data.dbg.alloc();
let geometry = new THREE.BufferGeometry();
if (position.length > 0)
geometry.addAttribute(
"position",
new THREE.Float32BufferAttribute(position, 3)
);
let pointColor = this.color;
let color = [];
for (var i = 0; i < position.length; i += 3) {
color.push(pointColor[0]);
color.push(pointColor[1]);
color.push(pointColor[2]);
}
this.move_points = function(box){
let points = this.lidar_points;
let trans = euler_angle_to_rotate_matrix_3by3(box.rotation);
let rotated_points = matmul(trans, points, 3);
let translation=[box.position.x, box.position.y, box.position.z];
let translated_points = rotated_points.map((p,i)=>{
return p + translation[i % 3];
});
geometry.addAttribute("color", new THREE.Float32BufferAttribute(color, 3));
let filtered_position = this.filterPoints(translated_points);
return filtered_position;
};
geometry.computeBoundingSphere();
// build material
let pointSize = this.sceneMeta.calib.aux_lidar[this.name].point_size;
if (!pointSize) pointSize = 1;
let material = new THREE.PointsMaterial({
size: pointSize,
vertexColors: THREE.VertexColors,
});
//material.size = 2;
material.sizeAttenuation = false;
this.move_lidar= function(box){
// build mesh
let mesh = new THREE.Points(geometry, material);
mesh.name = "lidar";
let translated_points = this.move_points(box);
return mesh;
};
let elements = this.buildGeometry(translated_points);
// remove old points
this.unload(true);
this.deleteAll(true);
this.buildGeometry = function (position) {
let points = this.buildPoints(position);
this.elements = elements;
//_self.points_backup = mesh;
if (this.go_cmd_received) // this should be always true
{
this.webglScene.add(this.elements.points);
if (!this.showPointsOnly)
this.elements.arrows.forEach(a=>this.webglScene.add(a));
}
return {
points: points,
};
};
this.move_points = function (box) {
let points = this.lidar_points;
let trans = euler_angle_to_rotate_matrix_3by3(box.rotation);
let rotated_points = matmul(trans, points, 3);
let translation = [box.position.x, box.position.y, box.position.z];
let translated_points = rotated_points.map((p, i) => {
return p + translation[i % 3];
});
let filtered_position = this.filterPoints(translated_points);
return filtered_position;
};
this.move_lidar = function (box) {
let translated_points = this.move_points(box);
let elements = this.buildGeometry(translated_points);
// remove old points
this.unload(true);
this.deleteAll(true);
this.elements = elements;
//_self.points_backup = mesh;
if (this.go_cmd_received) {
// this should be always true
this.webglScene.add(this.elements.points);
if (!this.showPointsOnly)
this.elements.arrows.forEach((a) => this.webglScene.add(a));
}
};
}
function AuxLidarManager(sceneMeta, world, frameInfo){
this.lidarList = [];
function AuxLidarManager(sceneMeta, world, frameInfo) {
this.lidarList = [];
if (world.data.cfg.enableAuxLidar && sceneMeta.aux_lidar){
let lidars = [];
for (let r in sceneMeta.calib.aux_lidar){
if (!sceneMeta.calib.aux_lidar[r].disable)
lidars.push(r);
}
if (world.data.cfg.enableAuxLidar && sceneMeta.aux_lidar) {
let lidars = [];
this.lidarList = lidars.map(name=>{
return new AuxLidar(sceneMeta, world, frameInfo, name);
});
for (let r in sceneMeta.calib.aux_lidar) {
if (!sceneMeta.calib.aux_lidar[r].disable) lidars.push(r);
}
this.getAllBoxes = function()
{
if (this.showCalibBox)
{
return this.lidarList.map(r=>r.calib_box);
}
else
{
return [];
}
};
this.lidarList = lidars.map((name) => {
return new AuxLidar(sceneMeta, world, frameInfo, name);
});
}
this.preloaded = function(){
for (let r in this.lidarList){
if (!this.lidarList[r].preloaded)
return false;
}
return true;
};
this.getAllBoxes = function () {
if (this.showCalibBox) {
return this.lidarList.map((r) => r.calib_box);
} else {
return [];
}
};
this.go = function(webglScene, on_go_finished){
this.lidarList.forEach(r=>r.go(webglScene, on_go_finished));
};
this.preloaded = function () {
for (let r in this.lidarList) {
if (!this.lidarList[r].preloaded) return false;
}
return true;
};
this.preload = function(on_preload_finished){
this.lidarList.forEach(r=>r.preload(on_preload_finished));
};
this.go = function (webglScene, on_go_finished) {
this.lidarList.forEach((r) => r.go(webglScene, on_go_finished));
};
this.unload = function(){
this.lidarList.forEach(r=>r.unload());
};
this.preload = function (on_preload_finished) {
this.lidarList.forEach((r) => r.preload(on_preload_finished));
};
this.deleteAll = function(){
this.lidarList.forEach(r=>r.deleteAll());
};
this.unload = function () {
this.lidarList.forEach((r) => r.unload());
};
this.getOperableObjects = function(){
return this.lidarList.flatMap(r=>r.getOperableObjects());
};
this.deleteAll = function () {
this.lidarList.forEach((r) => r.deleteAll());
};
this.showCalibBox = false;
this.showCalibBox = function(){
this.showCalibBox = true;
this.lidarList.forEach(r=>r.showCalibBox());
};
this.getOperableObjects = function () {
return this.lidarList.flatMap((r) => r.getOperableObjects());
};
this.hideCalibBox = function(){
this.showCalibBox = false;
this.lidarList.forEach(r=>r.hideCalibBox());
}
};
this.showCalibBox = false;
this.showCalibBox = function () {
this.showCalibBox = true;
this.lidarList.forEach((r) => r.showCalibBox());
};
this.hideCalibBox = function () {
this.showCalibBox = false;
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,153 +1,177 @@
import {rotation_matrix_to_euler_angle,euler_angle_to_rotate_matrix, matmul, transpose} from "./util.js"
import {
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"
function Calib(data, editor){
this.data = data;
this.editor = editor;
function Calib(data, editor) {
this.data = data;
this.editor = editor;
var euler_angle={x:0, y:0, y:0};
var translate = {x:0, y:0, z:0};
this.save_calibration = function(){
var scene_meta = data.meta[data.world.frameInfo.scene];
var active_camera_name = data.world.cameras.active_name;
var calib = scene_meta.calib.camera[active_camera_name]
var extrinsic = calib.extrinsic.map(function(x){return x*1.0;});
euler_angle = rotation_matrix_to_euler_angle(extrinsic);
translate = {
x: extrinsic[3]*1.0,
y: extrinsic[7]*1.0,
z: extrinsic[11]*1.0,
};
console.log(extrinsic, euler_angle, translate);
let matrix = euler_angle_to_rotate_matrix(euler_angle, translate)
console.log("restoreed matrix",matrix);
this.editor.infoBox.show("calib", JSON.stringify(matrix));
}
this.reset_calibration = function(){
// to be done
this.editor.imageContextManager.render_2d_image();
}
this.calib_box = null;
this.show_camera_pos = function(){
this.editor.viewManager.mainView.dumpPose();
var euler_angle = { x: 0, y: 0, y: 0 };
var translate = { x: 0, y: 0, z: 0 };
this.save_calibration = function () {
var scene_meta = data.meta[data.world.frameInfo.scene];
var active_camera_name = data.world.cameras.active_name;
var calib = scene_meta.calib.camera[active_camera_name];
var extrinsic = calib.extrinsic.map(function (x) {
return x * 1.0;
});
euler_angle = rotation_matrix_to_euler_angle(extrinsic);
translate = {
x: extrinsic[3] * 1.0,
y: extrinsic[7] * 1.0,
z: extrinsic[11] * 1.0,
};
// show a manipulating box
this.start_calibration = function(){
var scene_meta = this.data.meta[data.world.frameInfo.scene];
var active_camera_name = this.data.world.cameras.active_name;
var calib = scene_meta.calib.camera[active_camera_name]
var extrinsic = calib.extrinsic.map(function(x){return x*1.0;});
let viewMatrix = [0, -1, 0, 0, //row vector
0, 0, -1, 0,
1, 0, 0, 0,
0, 0, 0, 1];
function transpose_transmatrix(m){
//m=4*4
return [
m[0],m[4],m[8],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],
];
}
console.log(extrinsic, euler_angle, translate);
let matrix = euler_angle_to_rotate_matrix(euler_angle, translate);
console.log("restoreed matrix", matrix);
this.editor.infoBox.show("calib", JSON.stringify(matrix));
};
this.reset_calibration = function () {
// to be done
this.editor.imageContextManager.render_2d_image();
};
this.calib_box = null;
this.show_camera_pos = function () {
this.editor.viewManager.mainView.dumpPose();
};
// show a manipulating box
this.start_calibration = function () {
var scene_meta = this.data.meta[data.world.frameInfo.scene];
var active_camera_name = this.data.world.cameras.active_name;
var calib = scene_meta.calib.camera[active_camera_name];
var extrinsic = calib.extrinsic.map(function (x) {
return x * 1.0;
});
let viewMatrix = [
0,
-1,
0,
0, //row vector
0,
0,
-1,
0,
1,
0,
0,
0,
0,
0,
0,
1,
];
function transpose_transmatrix(m) {
//m=4*4
return [
m[0],
m[4],
m[8],
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),
transpose_transmatrix(extrinsic), 4);
var op_matrix = matmul(
transpose_transmatrix(viewMatrix),
transpose_transmatrix(extrinsic),
4
);
var euler_angle = rotation_matrix_to_euler_angle(op_matrix);
var translate = {
x: extrinsic[3] * 1.0,
y: extrinsic[7] * 1.0,
z: extrinsic[11] * 1.0,
};
var euler_angle = rotation_matrix_to_euler_angle(op_matrix);
var translate = {
x: extrinsic[3]*1.0,
y: extrinsic[7]*1.0,
z: extrinsic[11]*1.0,
};
console.log(euler_angle, translate);
this.show_camera_pos();
console.log(euler_angle, translate);
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],
y: translate.y,// + this.data.world.coordinatesOffset[1],
z: translate.z, // + this.data.world.coordinatesOffset[2]
},
{x:1,y:1, z:1},
{
x: euler_angle.x,
y: euler_angle.y,
z: euler_angle.z
},
"camera",
"camera"
);
this.data.world.scene.add(this.calib_box);
}
else{
console.log("calib box exists.");
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.z = translate.z;// + this.data.world.coordinatesOffset[2];
this.calib_box.rotation.x = euler_angle.x;
this.calib_box.rotation.y = euler_angle.y;
this.calib_box.rotation.z = euler_angle.z;
}
x: translate.x, // + this.data.world.coordinatesOffset[0],
y: translate.y, // + this.data.world.coordinatesOffset[1],
z: translate.z, // + this.data.world.coordinatesOffset[2]
},
{ x: 1, y: 1, z: 1 },
{
x: euler_angle.x,
y: euler_angle.y,
z: euler_angle.z,
},
"camera",
"camera"
);
this.data.world.scene.add(this.calib_box);
} else {
console.log("calib box exists.");
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.z = translate.z; // + this.data.world.coordinatesOffset[2];
this.calib_box.rotation.x = euler_angle.x;
this.calib_box.rotation.y = euler_angle.y;
this.calib_box.rotation.z = euler_angle.z;
}
console.log(this.calib_box);
this.editor.render();
this.calib_box.on_box_changed = ()=>{
console.log("calib box changed.");
let real_pos = {
x: this.calib_box.position.x,// - this.data.world.coordinatesOffset[0],
y: this.calib_box.position.y,// - this.data.world.coordinatesOffset[1],
z: this.calib_box.position.z,// - this.data.world.coordinatesOffset[2],
};
let extrinsic = euler_angle_to_rotate_matrix(this.calib_box.rotation, real_pos);
calib.extrinsic = transpose_transmatrix(matmul (viewMatrix, extrinsic, 4));
console.log("extrinsic", calib.extrinsic)
console.log("euler", euler_angle, "translate", translate);
this.editor.imageContextManager.render_2d_image();
}
console.log(this.calib_box);
this.editor.render();
this.calib_box.on_box_changed = () => {
console.log("calib box changed.");
};
function stop_calibration()
{
//tbd
let real_pos = {
x: this.calib_box.position.x, // - this.data.world.coordinatesOffset[0],
y: this.calib_box.position.y, // - this.data.world.coordinatesOffset[1],
z: this.calib_box.position.z, // - this.data.world.coordinatesOffset[2],
};
let extrinsic = euler_angle_to_rotate_matrix(
this.calib_box.rotation,
real_pos
);
calib.extrinsic = transpose_transmatrix(matmul(viewMatrix, extrinsic, 4));
console.log("extrinsic", calib.extrinsic);
console.log("euler", euler_angle, "translate", translate);
this.editor.imageContextManager.render_2d_image();
};
/*
};
function stop_calibration() {
//tbd
}
/*
function calibrate(ax, value){
var scene_meta = data.meta[data.world.frameInfo.scene];
@ -189,8 +213,6 @@ function Calib(data, editor){
update_image_box_projection(selected_box);
}
*/
};
}
export {Calib}
export { Calib };

@ -1,121 +1,106 @@
class Config {
//dataCfg = {
class Config{
//dataCfg = {
//disableLabels: true,
enablePreload = true;
color_points = "mono";
enableRadar = false;
enableAuxLidar = false;
enableDynamicGroundLevel = true;
coordinateSystem = 'utm';
point_size = 1;
point_brightness = 0.6;
box_opacity = 1;
show_background = true;
color_obj = "category";
theme = "dark";
enableFilterPoints = false;
filterPointsZ = 2.0;
batchModeInstNumber = 20;
batchModeSubviewSize = {width: 130, height: 450};
// edit on one box, apply to all selected boxes.
linkEditorsInBatchMode = false;
// only rotate z in 'auto/interpolate' algs
enableAutoRotateXY = false;
autoSave = true;
autoUpdateInterpolatedBoxes = true;
hideId = false;
hideCategory = false;
moveStep = 0.01; // ratio, percentage
rotateStep = Math.PI/360;
ignoreDistantObject = true;
///editorCfg
//disableSceneSelector = true;
//disableFrameSelector = true;
//disableCameraSelector = true;
//disableFastToolbox= true;
//disableMainView= true;
//disableMainImageContext = true;
//disableGrid = true;
//disableRangeCircle = true;
//disableAxis = true;
//disableMainViewKeyDown = true;
//projectRadarToImage = true;
//projectLidarToImage = true;
constructor()
{
}
//disableLabels: true,
enablePreload = true;
color_points = "mono";
enableRadar = false;
enableAuxLidar = false;
enableDynamicGroundLevel = true;
readItem(name, defaultValue, castFunc){
let ret = window.localStorage.getItem(name);
if (ret)
{
if (castFunc)
return castFunc(ret);
else
return ret;
}
else
{
return defaultValue;
}
}
coordinateSystem = "utm";
setItem(name, value)
{
this[name] = value;
if (typeof value == 'object')
value = JSON.stringify(value);
window.localStorage.setItem(name, value);
}
point_size = 1;
point_brightness = 0.6;
box_opacity = 1;
show_background = true;
color_obj = "category";
theme = "dark";
toBool(v)
{
return v==="true";
}
enableFilterPoints = false;
filterPointsZ = 2.0;
saveItems = [
["theme", null],
["enableRadar", this.toBool],
["enablePreload", this.toBool],
["enableAuxLidar", this.toBool],
["enableFilterPoints", this.toBool],
["filterPointsZ", parseFloat],
["color_points", null],
["coordinateSystem", null],
["batchModeInstNumber", parseInt],
["batchModeSubviewSize", JSON.parse],
["enableAutoRotateXY", this.toBool],
["autoUpdateInterpolatedBoxes", this.toBool],
];
load()
{
this.saveItems.forEach(item=>{
let key = item[0];
let castFunc = item[1];
this[key] = this.readItem(key, this[key], castFunc);
})
}
};
batchModeInstNumber = 20;
batchModeSubviewSize = { width: 130, height: 450 };
// edit on one box, apply to all selected boxes.
linkEditorsInBatchMode = false;
// only rotate z in 'auto/interpolate' algs
enableAutoRotateXY = false;
autoSave = true;
autoUpdateInterpolatedBoxes = true;
export {Config};
hideId = false;
hideCategory = false;
moveStep = 0.01; // ratio, percentage
rotateStep = Math.PI / 360;
ignoreDistantObject = true;
///editorCfg
//disableSceneSelector = true;
//disableFrameSelector = true;
//disableCameraSelector = true;
//disableFastToolbox= true;
//disableMainView= true;
//disableMainImageContext = true;
//disableGrid = true;
//disableRangeCircle = true;
//disableAxis = true;
//disableMainViewKeyDown = true;
//projectRadarToImage = true;
//projectLidarToImage = true;
constructor() {}
readItem(name, defaultValue, castFunc) {
let ret = window.localStorage.getItem(name);
if (ret) {
if (castFunc) return castFunc(ret);
else return ret;
} else {
return defaultValue;
}
}
setItem(name, value) {
this[name] = value;
if (typeof value == "object") value = JSON.stringify(value);
window.localStorage.setItem(name, value);
}
toBool(v) {
return v === "true";
}
saveItems = [
["theme", null],
["enableRadar", this.toBool],
["enablePreload", this.toBool],
["enableAuxLidar", this.toBool],
["enableFilterPoints", this.toBool],
["filterPointsZ", parseFloat],
["color_points", null],
["coordinateSystem", null],
["batchModeInstNumber", parseInt],
["batchModeSubviewSize", JSON.parse],
["enableAutoRotateXY", this.toBool],
["autoUpdateInterpolatedBoxes", this.toBool],
];
load() {
this.saveItems.forEach((item) => {
let key = item[0];
let castFunc = item[1];
this[key] = this.readItem(key, this[key], castFunc);
});
}
}
export { Config };

@ -1,347 +1,335 @@
import { globalKeyDownManager } from "./keydown_manager.js";
import {logger} from "./log.js";
class ConfigUi{
clickableItems = {
"#cfg-increase-size": (event)=>{
this.editor.data.scale_point_size(1.2);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-decrease-size": (event)=>{
this.editor.data.scale_point_size(0.8);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-increase-brightness": (event)=>{
this.editor.data.scale_point_brightness(1.2);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-decrease-brightness": (event)=>{
this.editor.data.scale_point_brightness(0.8);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-take-screenshot": (event)=>{
this.editor.downloadWebglScreenShot();
return true;
},
"#cfg-show-log": (event)=>{
logger.show();
return true;
},
"#cfg-start-calib":(event)=>{
this.editor.calib.start_calibration();
return true;
},
"#cfg-show-calib":(event)=>{
this.editor.calib.save_calibration();
return true;
},
// "#cfg-reset-calib":(event)=>{
// this.editor.calib.reset_calibration();
// return true;
// }
"#cfg-crop-scene": (event)=>{
this.editor.cropScene.show();
return true;
},
import { logger } from "./log.js";
class ConfigUi {
clickableItems = {
"#cfg-increase-size": (event) => {
this.editor.data.scale_point_size(1.2);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-decrease-size": (event) => {
this.editor.data.scale_point_size(0.8);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-increase-brightness": (event) => {
this.editor.data.scale_point_brightness(1.2);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-decrease-brightness": (event) => {
this.editor.data.scale_point_brightness(0.8);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-take-screenshot": (event) => {
this.editor.downloadWebglScreenShot();
return true;
},
"#cfg-show-log": (event) => {
logger.show();
return true;
},
"#cfg-start-calib": (event) => {
this.editor.calib.start_calibration();
return true;
},
"#cfg-show-calib": (event) => {
this.editor.calib.save_calibration();
return true;
},
// "#cfg-reset-calib":(event)=>{
// this.editor.calib.reset_calibration();
// return true;
// }
"#cfg-crop-scene": (event) => {
this.editor.cropScene.show();
return true;
},
};
changeableItems = {
"#cfg-theme-select": (event) => {
let theme = event.currentTarget.value;
//let scheme = document.documentElement.className;
document.documentElement.className = "theme-" + theme;
pointsGlobalConfig.setItem("theme", theme);
this.editor.viewManager.setColorScheme();
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-hide-box-checkbox": (event) => {
let checked = event.currentTarget.checked;
//let scheme = document.documentElement.className;
if (checked) this.editor.data.set_box_opacity(0);
else this.editor.data.set_box_opacity(1);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-hide-id-checkbox": (event) => {
let checked = event.currentTarget.checked;
this.editor.floatLabelManager.show_id(!checked);
return false;
},
"#cfg-hide-category-checkbox": (event) => {
let checked = event.currentTarget.checked;
this.editor.floatLabelManager.show_category(!checked);
return false;
},
"#cfg-hide-circle-ruler-checkbox": (event) => {
let checked = event.currentTarget.checked;
this.editor.showRangeCircle(!checked);
return false;
},
"#cfg-auto-rotate-xy-checkbox": (event) => {
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableAutoRotateXY", checked);
return false;
},
"#cfg-auto-update-interpolated-boxes-checkbox": (event) => {
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("autoUpdateInterpolatedBoxes", checked);
return false;
},
"#cfg-color-points-select": (event) => {
let value = event.currentTarget.value;
pointsGlobalConfig.setItem("color_points", value);
this.editor.data.worldList.forEach((w) => {
w.lidar.color_points();
w.lidar.update_points_color();
});
this.editor.render();
return false;
},
"#cfg-color-object-scheme": (event) => {
let value = event.currentTarget.value;
this.editor.data.set_obj_color_scheme(value);
this.editor.render();
this.editor.imageContextManager.render_2d_image();
this.editor.floatLabelManager.set_color_scheme(value);
this.editor.render2dLabels(this.editor.data.world);
this.editor.boxEditorManager.render();
return false;
},
"#cfg-batch-mode-inst-number": (event) => {
let batchSize = parseInt(event.currentTarget.value);
pointsGlobalConfig.setItem("batchModeInstNumber", batchSize);
this.editor.boxEditorManager.setBatchSize(batchSize);
return false;
},
"#cfg-coordinate-system-select": (event) => {
let coord = event.currentTarget.value;
pointsGlobalConfig.setItem("coordinateSystem", coord);
this.editor.data.worldList.forEach((w) => {
w.calcTransformMatrix();
});
this.editor.render();
},
"#cfg-data-aux-lidar-checkbox": (event) => {
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableAuxLidar", checked);
return false;
},
"#cfg-data-radar-checkbox": (event) => {
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableRadar", checked);
return false;
},
"#cfg-data-filter-points-checkbox": (event) => {
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableFilterPoints", checked);
return false;
},
"#cfg-data-filter-points-z": (event) => {
let z = event.currentTarget.value;
pointsGlobalConfig.setItem("filterPointsZ", z);
return false;
},
"#cfg-data-preload-checkbox": (event) => {
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enablePreload", checked);
return false;
},
};
ignoreItems = [
"#cfg-point-size",
"#cfg-point-brightness",
"#cfg-theme",
"#cfg-color-object",
"#cfg-menu-batch-mode-inst-number",
"#cfg-hide-box",
"#cfg-calib-camera-LiDAR",
"#cfg-experimental",
"#cfg-data",
];
subMenus = ["#cfg-experimental", "#cfg-data"];
constructor(button, wrapper, editor) {
this.button = button;
this.wrapper = wrapper;
this.editor = editor;
this.editorCfg = editor.editorCfg;
this.dataCfg = editor.data.cfg;
this.menu = this.wrapper.querySelector("#config-menu");
this.wrapper.onclick = () => {
this.hide();
};
changeableItems = {
"#cfg-theme-select":(event)=>{
let theme = event.currentTarget.value;
//let scheme = document.documentElement.className;
document.documentElement.className = "theme-"+theme;
pointsGlobalConfig.setItem("theme", theme);
this.editor.viewManager.setColorScheme();
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-hide-box-checkbox":(event)=>{
let checked = event.currentTarget.checked;
//let scheme = document.documentElement.className;
if (checked)
this.editor.data.set_box_opacity(0);
else
this.editor.data.set_box_opacity(1);
this.editor.render();
this.editor.boxEditorManager.render();
return false;
},
"#cfg-hide-id-checkbox":(event)=>{
let checked = event.currentTarget.checked;
this.editor.floatLabelManager.show_id(!checked);
return false;
},
"#cfg-hide-category-checkbox":(event)=>{
let checked = event.currentTarget.checked;
this.editor.floatLabelManager.show_category(!checked);
return false;
},
"#cfg-hide-circle-ruler-checkbox": (event)=>{
let checked = event.currentTarget.checked;
this.editor.showRangeCircle(!checked);
return false;
},
"#cfg-auto-rotate-xy-checkbox": (event)=>{
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableAutoRotateXY", checked);
return false;
},
'#cfg-auto-update-interpolated-boxes-checkbox': (event)=>{
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("autoUpdateInterpolatedBoxes", checked);
return false;
},
"#cfg-color-points-select": (event)=>{
let value = event.currentTarget.value;
pointsGlobalConfig.setItem("color_points", value);
this.editor.data.worldList.forEach(w=>{
w.lidar.color_points();
w.lidar.update_points_color();
});
this.editor.render();
return false;
},
"#cfg-color-object-scheme":(event)=>{
let value = event.currentTarget.value;
this.editor.data.set_obj_color_scheme(value);
this.editor.render();
this.editor.imageContextManager.render_2d_image();
this.editor.floatLabelManager.set_color_scheme(value);
this.editor.render2dLabels(this.editor.data.world);
this.editor.boxEditorManager.render();
return false;
},
"#cfg-batch-mode-inst-number":(event)=>{
let batchSize = parseInt(event.currentTarget.value);
pointsGlobalConfig.setItem("batchModeInstNumber", batchSize);
this.editor.boxEditorManager.setBatchSize(batchSize);
return false;
},
"#cfg-coordinate-system-select": (event)=>{
let coord = event.currentTarget.value;
pointsGlobalConfig.setItem("coordinateSystem", coord);
this.editor.data.worldList.forEach(w=>{
w.calcTransformMatrix();
});
this.editor.render();
},
"#cfg-data-aux-lidar-checkbox": (event)=>{
let checked = event.currentTarget.checked;
this.button.onclick = (event) => {
this.show(event.currentTarget);
};
pointsGlobalConfig.setItem("enableAuxLidar", checked);
return false;
},
"#cfg-data-radar-checkbox": (event)=>{
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableRadar", checked);
return false;
},
"#cfg-data-filter-points-checkbox": (event)=>{
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enableFilterPoints", checked);
return false;
},
"#cfg-data-filter-points-z": (event)=>{
let z = event.currentTarget.value;
pointsGlobalConfig.setItem("filterPointsZ", z);
return false;
},
"#cfg-data-preload-checkbox": (event)=>{
let checked = event.currentTarget.checked;
pointsGlobalConfig.setItem("enablePreload", checked);
return false;
for (let item in this.clickableItems) {
this.menu.querySelector(item).onclick = (event) => {
let ret = this.clickableItems[item](event);
if (ret) {
this.hide();
}
};
event.stopPropagation();
};
}
ignoreItems = [
"#cfg-point-size",
"#cfg-point-brightness",
"#cfg-theme",
"#cfg-color-object",
"#cfg-menu-batch-mode-inst-number",
"#cfg-hide-box",
"#cfg-calib-camera-LiDAR",
"#cfg-experimental",
"#cfg-data",
];
subMenus = [
"#cfg-experimental",
"#cfg-data",
];
constructor(button, wrapper, editor)
{
this.button = button;
this.wrapper = wrapper;
this.editor = editor;
this.editorCfg = editor.editorCfg;
this.dataCfg = editor.data.cfg;
this.menu = this.wrapper.querySelector("#config-menu");
this.wrapper.onclick = ()=>{
this.hide();
for (let item in this.changeableItems) {
this.menu.querySelector(item).onchange = (event) => {
let ret = this.changeableItems[item](event);
if (ret) {
this.hide();
}
this.button.onclick = (event)=>{
this.show(event.currentTarget);
}
event.stopPropagation();
};
}
for (let item in this.clickableItems)
this.ignoreItems.forEach((item) => {
this.menu.querySelector(item).onclick = (event) => {
{
this.menu.querySelector(item).onclick = (event)=>{
let ret = this.clickableItems[item](event);
if (ret)
{
this.hide();
}
event.stopPropagation();
}
event.stopPropagation();
}
for (let item in this.changeableItems)
{
this.menu.querySelector(item).onchange = (event)=>{
let ret = this.changeableItems[item](event);
if (ret)
{
this.hide();
}
event.stopPropagation();
}
};
});
this.subMenus.forEach((item) => {
this.menu.querySelector(item).onmouseenter = function (event) {
if (this.timerId) {
clearTimeout(this.timerId);
this.timerId = null;
}
this.ignoreItems.forEach(item=>{
this.menu.querySelector(item).onclick = (event)=>{
{
event.stopPropagation();
}
}
});
this.subMenus.forEach(item=>{
this.menu.querySelector(item).onmouseenter = function(event){
if (this.timerId)
{
clearTimeout(this.timerId);
this.timerId = null;
}
event.currentTarget.querySelector(item +"-submenu").style.display="inherit";
}
this.menu.querySelector(item).onmouseleave = function(event){
let ui = event.currentTarget.querySelector(item +"-submenu");
this.timerId = setTimeout(()=>{
ui.style.display="none";
this.timerId = null;
},
200);
}
});
this.menu.onclick = (event)=>{
event.stopPropagation();
};
// init ui
this.menu.querySelector("#cfg-theme-select").value = pointsGlobalConfig.theme;
this.menu.querySelector("#cfg-data-aux-lidar-checkbox").checked = pointsGlobalConfig.enableAuxLidar;
this.menu.querySelector("#cfg-data-radar-checkbox").checked = pointsGlobalConfig.enableRadar;
this.menu.querySelector("#cfg-color-points-select").value = pointsGlobalConfig.color_points;
this.menu.querySelector("#cfg-coordinate-system-select").value = pointsGlobalConfig.coordinateSystem;
this.menu.querySelector("#cfg-batch-mode-inst-number").value = pointsGlobalConfig.batchModeInstNumber;
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){
this.wrapper.style.display="inherit";
this.menu.style.right = "0px";
this.menu.style.top = target.offsetHeight + "px";
globalKeyDownManager.register((event)=>false, 'config');
}
hide(){
globalKeyDownManager.deregister('config');
this.wrapper.style.display="none";
}
event.currentTarget.querySelector(item + "-submenu").style.display =
"inherit";
};
this.menu.querySelector(item).onmouseleave = function (event) {
let ui = event.currentTarget.querySelector(item + "-submenu");
this.timerId = setTimeout(() => {
ui.style.display = "none";
this.timerId = null;
}, 200);
};
});
this.menu.onclick = (event) => {
event.stopPropagation();
};
// init ui
this.menu.querySelector("#cfg-theme-select").value =
pointsGlobalConfig.theme;
this.menu.querySelector("#cfg-data-aux-lidar-checkbox").checked =
pointsGlobalConfig.enableAuxLidar;
this.menu.querySelector("#cfg-data-radar-checkbox").checked =
pointsGlobalConfig.enableRadar;
this.menu.querySelector("#cfg-color-points-select").value =
pointsGlobalConfig.color_points;
this.menu.querySelector("#cfg-coordinate-system-select").value =
pointsGlobalConfig.coordinateSystem;
this.menu.querySelector("#cfg-batch-mode-inst-number").value =
pointsGlobalConfig.batchModeInstNumber;
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) {
this.wrapper.style.display = "inherit";
this.menu.style.right = "0px";
this.menu.style.top = target.offsetHeight + "px";
globalKeyDownManager.register((event) => false, "config");
}
hide() {
globalKeyDownManager.deregister("config");
this.wrapper.style.display = "none";
}
}
export {ConfigUi}
export { ConfigUi };

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

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

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

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

File diff suppressed because it is too large Load Diff

@ -1,78 +1,65 @@
class EgoPose
{
constructor(sceneMeta, world, frameInfo)
{
this.world = world;
this.data = this.world.data;
this.sceneMeta = sceneMeta;
}
preload(on_preload_finished)
{
this.on_preload_finished = on_preload_finished;
this.load_ego_pose();
};
load_ego_pose(){
var xhr = new XMLHttpRequest();
// we defined the xhr
var _self = this;
xhr.onreadystatechange = function () {
if (this.readyState != 4) return;
if (this.status == 200) {
let egoPose = JSON.parse(this.responseText);
_self.egoPose = egoPose;
}
console.log(_self.world.frameInfo.frame, "egopose", "loaded");
_self.preloaded = true;
if (_self.on_preload_finished){
_self.on_preload_finished();
}
if (_self.go_cmd_received){
_self.go(this.webglScene, this.on_go_finished);
}
// 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.send();
class EgoPose {
constructor(sceneMeta, world, frameInfo) {
this.world = world;
this.data = this.world.data;
this.sceneMeta = sceneMeta;
}
preload(on_preload_finished) {
this.on_preload_finished = on_preload_finished;
this.load_ego_pose();
}
load_ego_pose() {
var xhr = new XMLHttpRequest();
// we defined the xhr
var _self = this;
xhr.onreadystatechange = function () {
if (this.readyState != 4) return;
if (this.status == 200) {
let egoPose = JSON.parse(this.responseText);
_self.egoPose = egoPose;
}
console.log(_self.world.frameInfo.frame, "egopose", "loaded");
_self.preloaded = true;
if (_self.on_preload_finished) {
_self.on_preload_finished();
}
if (_self.go_cmd_received) {
_self.go(this.webglScene, this.on_go_finished);
}
// 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.send();
}
go_cmd_received = false;
on_go_finished = null;
go(webglScene, on_go_finished) {
if (this.preloaded) {
if (on_go_finished) on_go_finished();
} else {
this.go_cmd_received = true;
this.on_go_finished = on_go_finished;
}
}
go_cmd_received = false;
on_go_finished = null;
go(webglScene, on_go_finished)
{
if (this.preloaded){
if (on_go_finished)
on_go_finished();
} else {
this.go_cmd_received = true;
this.on_go_finished = on_go_finished;
}
};
unload()
{
};
unload() {}
}
export{EgoPose}
export { EgoPose };

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

File diff suppressed because it is too large Load Diff

@ -1,156 +1,192 @@
import { CubeRefractionMapping } from "./lib/three.module.js";
import {saveWorldList} from "./save.js"
var Header=function(ui, data, cfg, onSceneChanged, onFrameChanged, onObjectSelected, onCameraChanged){
this.ui = ui;
this.data = data;
this.cfg = cfg;
this.boxUi = ui.querySelector("#box");
this.refObjUi = ui.querySelector("#ref-obj");
this.sceneSelectorUi = ui.querySelector("#scene-selector");
this.frameSelectorUi = ui.querySelector("#frame-selector");
this.objectSelectorUi = ui.querySelector("#object-selector");
this.cameraSelectorUi = ui.querySelector("#camera-selector");
this.changedMarkUi = ui.querySelector("#changed-mark");
this.onSceneChanged = onSceneChanged;
this.onFrameChanged = onFrameChanged;
this.onObjectSelected = onObjectSelected;
this.onCameraChanged = onCameraChanged;
if (cfg.disableSceneSelector){
this.sceneSelectorUi.style.display="none";
}
if (cfg.disableFrameSelector){
this.frameSelectorUi.style.display="none";
}
if (cfg.disableCameraSelector){
this.cameraSelectorUi.style.display="none";
}
// update scene selector ui
this.updateSceneList = function(sceneDescList){
let scene_selector_str = "<option>--scene--</option>";
for (let scene in sceneDescList)
{
if (data.sceneDescList[scene])
scene_selector_str += "<option value="+scene +">"+scene + " - " +data.sceneDescList[scene].scene + "</option>";
else
scene_selector_str += "<option value="+scene +">"+scene+ "</option>";
}
this.ui.querySelector("#scene-selector").innerHTML = scene_selector_str;
}
this.updateSceneList(this.data.sceneDescList);
this.ui.querySelector("#btn-reload-scene-list").onclick = (event)=>{
let curentValue = this.sceneSelectorUi.value;
this.data.readSceneList().then((sceneDescList=>{
this.updateSceneList(sceneDescList);
this.sceneSelectorUi.value = curentValue;
}))
}
this.sceneSelectorUi.onchange = (e)=>{this.onSceneChanged(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.objectSelectorUi.value = id;
import { saveWorldList } from "./save.js";
var Header = function (
ui,
data,
cfg,
onSceneChanged,
onFrameChanged,
onObjectSelected,
onCameraChanged
) {
this.ui = ui;
this.data = data;
this.cfg = cfg;
this.boxUi = ui.querySelector("#box");
this.refObjUi = ui.querySelector("#ref-obj");
this.sceneSelectorUi = ui.querySelector("#scene-selector");
this.frameSelectorUi = ui.querySelector("#frame-selector");
this.objectSelectorUi = ui.querySelector("#object-selector");
this.cameraSelectorUi = ui.querySelector("#camera-selector");
this.changedMarkUi = ui.querySelector("#changed-mark");
this.onSceneChanged = onSceneChanged;
this.onFrameChanged = onFrameChanged;
this.onObjectSelected = onObjectSelected;
this.onCameraChanged = onCameraChanged;
if (cfg.disableSceneSelector) {
this.sceneSelectorUi.style.display = "none";
}
if (cfg.disableFrameSelector) {
this.frameSelectorUi.style.display = "none";
}
if (cfg.disableCameraSelector) {
this.cameraSelectorUi.style.display = "none";
}
// update scene selector ui
this.updateSceneList = function (sceneDescList) {
let scene_selector_str = "<option>--scene--</option>";
for (let scene in sceneDescList) {
if (data.sceneDescList[scene])
scene_selector_str +=
"<option value=" +
scene +
">" +
scene +
" - " +
data.sceneDescList[scene].scene +
"</option>";
else
scene_selector_str +=
"<option value=" + scene + ">" + scene + "</option>";
}
this.clear_box_info = function(){
this.boxUi.innerHTML = '';
};
this.update_box_info = function(box){
var scale = box.scale;
var pos = box.position;
var rotation = box.rotation;
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);
this.boxUi.innerHTML = "<span>" + box.obj_type +"-"+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'>" +
(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'>" +
points_number + "</span> ";
if (box.follows){
this.boxUi.innerHTML += "| F:"+box.follows.obj_track_id;
}
},
this.set_ref_obj = function(marked_object){
this.refObjUi.innerHTML="| Ref: "+marked_object.scene+"/"+marked_object.frame+": "+marked_object.ann.obj_type+"-"+marked_object.ann.obj_id;
},
this.set_frame_info =function(scene, frame, on_scene_changed){
if (this.sceneSelectorUi.value != scene){
this.sceneSelectorUi.value = scene;
on_scene_changed(scene);
}
this.frameSelectorUi.value = 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 = 'ui-button alarm-mark';
}
else
{
this.ui.querySelector("#changed-mark").className = 'ui-button';
}
this.ui.querySelector("#scene-selector").innerHTML = scene_selector_str;
};
this.updateSceneList(this.data.sceneDescList);
this.ui.querySelector("#btn-reload-scene-list").onclick = (event) => {
let curentValue = this.sceneSelectorUi.value;
this.data.readSceneList().then((sceneDescList) => {
this.updateSceneList(sceneDescList);
this.sceneSelectorUi.value = curentValue;
});
};
this.sceneSelectorUi.onchange = (e) => {
this.onSceneChanged(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.objectSelectorUi.value = id;
};
this.clear_box_info = function () {
this.boxUi.innerHTML = "";
};
(this.update_box_info = function (box) {
var scale = box.scale;
var pos = box.position;
var rotation = box.rotation;
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);
this.boxUi.innerHTML =
"<span>" +
box.obj_type +
"-" +
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'>" +
((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'>" +
points_number +
"</span> ";
if (box.follows) {
this.boxUi.innerHTML += "| F:" + box.follows.obj_track_id;
}
this.ui.querySelector("#changed-mark").onmouseenter = ()=>{
let items = "";
let frames = this.data.worldList.filter(w=>w.annotation.modified).map(w=>w.frameInfo);
frames.forEach(f=>{
items += "<div class='modified-world-item'>" + f.frame + '</div>';
});
if (frames.length > 0){
this.ui.querySelector("#changed-world-list").innerHTML = items;
this.ui.querySelector("#changed-world-list-wrapper").style.display = 'inherit';
}
}),
(this.set_ref_obj = function (marked_object) {
this.refObjUi.innerHTML =
"| Ref: " +
marked_object.scene +
"/" +
marked_object.frame +
": " +
marked_object.ann.obj_type +
"-" +
marked_object.ann.obj_id;
}),
(this.set_frame_info = function (scene, frame, on_scene_changed) {
if (this.sceneSelectorUi.value != scene) {
this.sceneSelectorUi.value = scene;
on_scene_changed(scene);
}
this.frameSelectorUi.value = 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 =
"ui-button alarm-mark";
} else {
this.ui.querySelector("#changed-mark").className = "ui-button";
}
});
this.ui.querySelector("#changed-mark").onmouseenter = () => {
let items = "";
let frames = this.data.worldList
.filter((w) => w.annotation.modified)
.map((w) => w.frameInfo);
frames.forEach((f) => {
items += "<div class='modified-world-item'>" + f.frame + "</div>";
});
if (frames.length > 0) {
this.ui.querySelector("#changed-world-list").innerHTML = items;
this.ui.querySelector("#changed-world-list-wrapper").style.display =
"inherit";
}
};
this.ui.querySelector("#changed-mark").onmouseleave = ()=>{
this.ui.querySelector("#changed-world-list-wrapper").style.display = 'none';
}
this.ui.querySelector("#changed-mark").onmouseleave = () => {
this.ui.querySelector("#changed-world-list-wrapper").style.display = "none";
};
this.ui.querySelector("#save-button").onclick = ()=>{
saveWorldList(this.data.worldList);
}
this.ui.querySelector("#save-button").onclick = () => {
saveWorldList(this.data.worldList);
};
};
export {Header}
export { Header };

File diff suppressed because it is too large Load Diff

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

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

File diff suppressed because it is too large Load Diff

@ -1,202 +1,213 @@
import { PopupDialog } from "./popup_dialog.js";
class LogWindow extends PopupDialog{
mouseDown = false;
mouseDwwnPos = {};
constructor(ui, btn)
{
super(ui);
this.btn = btn;
this.svg = btn.querySelector("#log-svg");
this.logsContentUi = this.ui.querySelector("#content-logs");
this.errorsContentUi = this.ui.querySelector("#content-errors");
this.clearBtn = this.ui.querySelector("#btn-clear");
this.clearBtn.onclick = ()=>{ this.logsContentUi.innerHTML = ""; };
this.log("Welcome!");
this.logBtn = this.ui.querySelector("#tab-log");
this.errorBtn = this.ui.querySelector("#tab-error");
this.logBtn.onclick= ()=>{
this.logBtn.className = "tab-button tab-selected";
this.errorBtn.className = "tab-button";
this.logsContentUi.style.display = 'inherit';
this.errorsContentUi.style.display = 'none';
}
this.errorBtn.onclick= ()=>{
this.errorBtn.className = "tab-button tab-selected";
this.logBtn.className = "tab-button";
this.logsContentUi.style.display = 'none';
this.errorsContentUi.style.display = 'inherit';
}
}
setErrorsContent(errors)
{
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);
this.errorsContentUi.innerHTML = text;
this.errorsContentUi.querySelectorAll(".log-object-frame-id").forEach(ele=>{
ele.onclick = (event)=>{
let obj = event.currentTarget.innerHTML.split(",");
console.log("click", obj);
window.editor.currentMainEditor.gotoObjectFrame(...obj); //frameid, objid
}
});
}
setUi(ui)
{
}
show()
{
super.show();
}
gettime() {
let d = new Date();
return "" + d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
class LogWindow extends PopupDialog {
mouseDown = false;
mouseDwwnPos = {};
constructor(ui, btn) {
super(ui);
this.btn = btn;
this.svg = btn.querySelector("#log-svg");
this.logsContentUi = this.ui.querySelector("#content-logs");
this.errorsContentUi = this.ui.querySelector("#content-errors");
this.clearBtn = this.ui.querySelector("#btn-clear");
this.clearBtn.onclick = () => {
this.logsContentUi.innerHTML = "";
};
this.log("Welcome!");
this.logBtn = this.ui.querySelector("#tab-log");
this.errorBtn = this.ui.querySelector("#tab-error");
this.logBtn.onclick = () => {
this.logBtn.className = "tab-button tab-selected";
this.errorBtn.className = "tab-button";
this.logsContentUi.style.display = "inherit";
this.errorsContentUi.style.display = "none";
};
this.errorBtn.onclick = () => {
this.errorBtn.className = "tab-button tab-selected";
this.logBtn.className = "tab-button";
this.logsContentUi.style.display = "none";
this.errorsContentUi.style.display = "inherit";
};
}
setErrorsContent(errors) {
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);
this.errorsContentUi.innerHTML = text;
this.errorsContentUi
.querySelectorAll(".log-object-frame-id")
.forEach((ele) => {
ele.onclick = (event) => {
let obj = event.currentTarget.innerHTML.split(",");
console.log("click", obj);
window.editor.currentMainEditor.gotoObjectFrame(...obj); //frameid, objid
};
});
}
setUi(ui) {}
show() {
super.show();
}
gettime() {
let d = new Date();
return (
"" +
d.getFullYear() +
"-" +
(d.getMonth() + 1) +
"-" +
d.getDate() +
" " +
d.getHours() +
":" +
d.getMinutes() +
":" +
d.getSeconds()
);
}
autoScroll = true;
updateAutoScrollFlag() {
let div = this.logsContentUi;
this.autoScroll = div.scrollHeight - 10 < div.scrollTop + div.clientHeight;
}
autoScrollOutput() {
let div = this.logsContentUi;
if (this.autoScroll) div.scrollTop = div.scrollHeight;
}
isInt(n) {
return n % 1 === 0;
}
buildLogStr(args) {
let thisstr = "";
for (let i in args) {
if (typeof args[i] == "number") {
thisstr +=
" <span class='number'>" +
(isInt(args[i]) ? args[i] : args[i].toFixed(6)) +
"</span>";
} else if ([".", ",", ":", ";"].find((c) => c == args[i])) {
thisstr += args[i];
} else {
thisstr += " " + args[i];
}
}
autoScroll = true;
updateAutoScrollFlag()
{
let div = this.logsContentUi;
this.autoScroll = (div.scrollHeight-10 < div.scrollTop + div.clientHeight);
}
autoScrollOutput(){
let div = this.logsContentUi;
if (this.autoScroll)
div.scrollTop = div.scrollHeight;
}
isInt(n) {
return n % 1 === 0;
}
buildLogStr(args) {
let thisstr = "";
for (let i in args) {
if (typeof args[i] == "number") {
thisstr += " <span class='number'>" + (isInt(args[i]) ? args[i] : args[i].toFixed(6)) + "</span>";
} else if ([".", ",", ":", ";"].find((c) => c == args[i])) {
thisstr += args[i];
} else {
thisstr += " " + args[i];
}
}
return thisstr;
}
logcolor(color) {
this.updateAutoScrollFlag();
let args = [...arguments];
console.log(...args.slice(1));
let old_content = this.logsContentUi.innerHTML;
let thisstr = this.gettime() + " ";
thisstr += this.buildLogStr(args.slice(1));
this.logid++;
this.logsContentUi.innerHTML = old_content + "<div id='log-" + this.logid + "' class='" + color + "'>" + thisstr + "</div>";
return thisstr;
}
this.autoScrollOutput();
}
logid = 0;
maxLogLength = 10000; // stringLength;
log() {
logcolor(color) {
this.updateAutoScrollFlag();
let args = [...arguments];
console.log(...args.slice(1));
let old_content = this.logsContentUi.innerHTML;
this.svg.style.fill= this.logid %2 ? "red" : "green";
let thisstr = this.gettime() + " ";
thisstr += this.buildLogStr(args.slice(1));
this.updateAutoScrollFlag();
console.log(...arguments);
let old_content = this.logsContentUi.innerHTML;
this.logid++;
let thisstr = this.gettime() + " ";
//let thisstr = "";
thisstr += this.buildLogStr(arguments);
this.logsContentUi.innerHTML =
old_content +
"<div id='log-" +
this.logid +
"' class='" +
color +
"'>" +
thisstr +
"</div>";
this.logid++;
if (old_content.length > this.maxLogLength)
{
old_content = old_content.slice(old_content.length-this.maxLogLength);
let firstLogPos = old_content.search("<div id=");
old_content = old_content.slice(firstLogPos);
}
this.autoScrollOutput();
}
this.logsContentUi.innerHTML = old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>";
this.autoScrollOutput();
}
logid = 0;
maxLogLength = 10000; // stringLength;
log() {
this.svg.style.fill = this.logid % 2 ? "red" : "green";
logappend() {
//console.log(...arguments);
this.updateAutoScrollFlag();
let thisstr = this.buildLogStr(arguments);
this.logsContentUi.querySelector("#log-" + this.logid).innerHTML += thisstr;
this.autoScrollOutput();
}
this.updateAutoScrollFlag();
logappendcolor(color) {
this.updateAutoScrollFlag();
let args = [...arguments];
let thisstr = this.buildLogStr(args.slice(1));
let div = this.logsContentUi.querySelector("#log-" + this.logid);
div.className = color;
div.innerHTML += thisstr;
this.autoScrollOutput();
}
console.log(...arguments);
let old_content = this.logsContentUi.innerHTML;
logonce() {
this.updateAutoScrollFlag();
let old_content = this.logsContentUi.innerHTML;
let thisstr = this.gettime() + " ";
//let thisstr = "";
thisstr += this.buildLogStr(arguments);
let thisstr = this.gettime() + " ";
thisstr += this.buildLogStr(arguments);
this.logid++;
let laststr = this.logsContentUi.querySelector("#log-" + this.logid);
if (laststr && laststr.innerHTML && thisstr == laststr.innerHTML)
return;
this.logid++;
this.logsContentUi.innerHTML = old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>";
this.autoScrollOutput();
if (old_content.length > this.maxLogLength) {
old_content = old_content.slice(old_content.length - this.maxLogLength);
let firstLogPos = old_content.search("<div id=");
old_content = old_content.slice(firstLogPos);
}
this.logsContentUi.innerHTML =
old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>";
this.autoScrollOutput();
}
logappend() {
//console.log(...arguments);
this.updateAutoScrollFlag();
let thisstr = this.buildLogStr(arguments);
this.logsContentUi.querySelector("#log-" + this.logid).innerHTML += thisstr;
this.autoScrollOutput();
}
logappendcolor(color) {
this.updateAutoScrollFlag();
let args = [...arguments];
let thisstr = this.buildLogStr(args.slice(1));
let div = this.logsContentUi.querySelector("#log-" + this.logid);
div.className = color;
div.innerHTML += thisstr;
this.autoScrollOutput();
}
logonce() {
this.updateAutoScrollFlag();
let old_content = this.logsContentUi.innerHTML;
let thisstr = this.gettime() + " ";
thisstr += this.buildLogStr(arguments);
let laststr = this.logsContentUi.querySelector("#log-" + this.logid);
if (laststr && laststr.innerHTML && thisstr == laststr.innerHTML) return;
this.logid++;
this.logsContentUi.innerHTML =
old_content + "<div id='log-" + this.logid + "'>" + thisstr + "</div>";
this.autoScrollOutput();
}
}
let logger = null;
function create_logger(ui, btn){
logger = new LogWindow(ui, btn);
function create_logger(ui, btn) {
logger = new LogWindow(ui, btn);
}
export{logger, create_logger};
export { logger, create_logger };

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

File diff suppressed because it is too large Load Diff

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

@ -1,172 +1,190 @@
// size is the dimension of the object in x/y/z axis, with unit meter.
class ObjectCategory
{
obj_type_map = {
Car: {color: '#86af49', size:[4.5, 1.8, 1.5], attr:["door open", "trunk open"]},
Pedestrian: {color: '#ff0000', size:[0.4, 0.5, 1.7], attr:["umbrella", "sitting", "squating", "bending over", "luggage"]},
Van: {color: '#00ff00', size:[4.5, 1.8, 1.5], attr:["door open", "trunk open"]},
Bus: {color: '#ffff00', size:[13, 3, 3.5]},
Truck: {color: '#00ffff', size:[10., 2.8, 3]},
ScooterRider: {color: '#ff8800', size:[1.6, 0.6, 1.6], attr:["umbrella", "1 passenger", "2 passengers", "3 passengers"]},
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]},
BabyCart: {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]},
FireHydrant: {color: '#ff0000', size:[0.4, 0.4, 0.6]},
SaftyTriangle: {color: '#ff0000', size:[0.3, 0.4, 0.4]},
PlatformCart: {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]},
TrafficBarrier: {color: '#ff0000', size:[1.5, 0.3, 1.2]},
LongVehicle: {color: '#ff0000', size:[16, 3, 3]},
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]},
Excavator: {color: '#00ffff', size:[6., 3, 3]},
Animal: {color: '#00aaff', size:[1.6, 0.6, 1.2]},
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]},
FreightTricycle: {color: '#00aaff', size:[2.6, 1.0, 1.6]},
Crane: {color: '#00aaff', size:[5.0, 1.2, 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]},
Unknown: {color: '#008888', size:[4.5, 1.8, 1.5]},
Unknown1: {color: '#008888', size:[4.5, 1.8, 1.5]},
Unknown2: {color: '#008888', size:[4.5, 1.8, 1.5]},
Unknown3: {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(){
}
popularCategories = ["Car", "Pedestrian", "Van", "Bus", "Truck", "Scooter", "ScooterRider", "Bicycle", "BicycleRider"];
guess_obj_type_by_dimension(scale){
var max_score = 0;
var max_name = 0;
this.popularCategories.forEach(i=>{
var o = this.obj_type_map[i];
var scorex = o.size[0]/scale.x;
var scorey = o.size[1]/scale.y;
var scorez = o.size[2]/scale.z;
if (scorex>1) scorex = 1/scorex;
if (scorey>1) scorey = 1/scorey;
if (scorez>1) scorez = 1/scorez;
if (scorex + scorey + scorez > max_score){
max_score = scorex + scorey + scorez;
max_name = i;
}
});
console.log("guess type", max_name);
return max_name;
class ObjectCategory {
obj_type_map = {
Car: {
color: "#86af49",
size: [4.5, 1.8, 1.5],
attr: ["door open", "trunk open"],
},
Pedestrian: {
color: "#ff0000",
size: [0.4, 0.5, 1.7],
attr: ["umbrella", "sitting", "squating", "bending over", "luggage"],
},
Van: {
color: "#00ff00",
size: [4.5, 1.8, 1.5],
attr: ["door open", "trunk open"],
},
Bus: { color: "#ffff00", size: [13, 3, 3.5] },
Truck: { color: "#00ffff", size: [10, 2.8, 3] },
ScooterRider: {
color: "#ff8800",
size: [1.6, 0.6, 1.6],
attr: ["umbrella", "1 passenger", "2 passengers", "3 passengers"],
},
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]},
BabyCart: { 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] },
FireHydrant: { color: "#ff0000", size: [0.4, 0.4, 0.6] },
SaftyTriangle: { color: "#ff0000", size: [0.3, 0.4, 0.4] },
PlatformCart: { 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] },
TrafficBarrier: { color: "#ff0000", size: [1.5, 0.3, 1.2] },
LongVehicle: { color: "#ff0000", size: [16, 3, 3] },
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] },
Excavator: { color: "#00ffff", size: [6, 3, 3] },
Animal: { color: "#00aaff", size: [1.6, 0.6, 1.2] },
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] },
FreightTricycle: { color: "#00aaff", size: [2.6, 1.0, 1.6] },
Crane: { color: "#00aaff", size: [5.0, 1.2, 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] },
Unknown: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown1: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown2: { color: "#008888", size: [4.5, 1.8, 1.5] },
Unknown3: { 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() {}
popularCategories = [
"Car",
"Pedestrian",
"Van",
"Bus",
"Truck",
"Scooter",
"ScooterRider",
"Bicycle",
"BicycleRider",
];
guess_obj_type_by_dimension(scale) {
var max_score = 0;
var max_name = 0;
this.popularCategories.forEach((i) => {
var o = this.obj_type_map[i];
var scorex = o.size[0] / scale.x;
var scorey = o.size[1] / scale.y;
var scorez = o.size[2] / scale.z;
if (scorex > 1) scorex = 1 / scorex;
if (scorey > 1) scorey = 1 / scorey;
if (scorez > 1) scorez = 1 / scorez;
if (scorex + scorey + scorez > max_score) {
max_score = scorex + scorey + scorez;
max_name = i;
}
});
console.log("guess type", max_name);
return max_name;
}
global_color_idx = 0;
get_color_by_id(id) {
let idx = parseInt(id);
if (!idx) {
idx = this.global_color_idx;
this.global_color_idx += 1;
}
global_color_idx = 0;
get_color_by_id(id){
let idx = parseInt(id);
idx %= 33;
idx = (idx * 19) % 33;
if (!idx)
{
idx = this.global_color_idx;
this.global_color_idx += 1;
}
return {
x: (idx * 8) / 256.0,
y: 1 - (idx * 8) / 256.0,
z: idx < 16 ? (idx * 2 * 8) / 256.0 : ((32 - idx) * 2 * 8) / 256.0,
};
}
idx %= 33;
idx = idx*19 % 33;
get_color_by_category(category) {
let target_color_hex = parseInt(
"0x" + this.get_obj_cfg_by_type(category).color.slice(1)
);
return {
x: idx*8/256.0,
y: 1- idx*8/256.0,
z: (idx<16)?(idx*2*8/256.0):((32-idx)*2*8/256.0),
};
}
get_color_by_category(category){
let target_color_hex = parseInt("0x"+this.get_obj_cfg_by_type(category).color.slice(1));
return {
x: (target_color_hex/256/256)/255.0,
y: (target_color_hex/256 % 256)/255.0,
z: (target_color_hex % 256)/255.0,
};
}
return {
x: target_color_hex / 256 / 256 / 255.0,
y: ((target_color_hex / 256) % 256) / 255.0,
z: (target_color_hex % 256) / 255.0,
};
}
get_obj_cfg_by_type(name){
if (this.obj_type_map[name]){
return this.obj_type_map[name];
}
else{
return this.obj_type_map["Unknown"];
}
get_obj_cfg_by_type(name) {
if (this.obj_type_map[name]) {
return this.obj_type_map[name];
} else {
return this.obj_type_map["Unknown"];
}
}
// name_array = []
// build_name_array(){
// for (var n in this.obj_type_map){
// name_array.push(n);
// }
// }
// name_array = []
// build_name_array(){
// for (var n in this.obj_type_map){
// name_array.push(n);
// }
// }
// get_next_obj_type_name(name){
// get_next_obj_type_name(name){
// if (name_array.length == 0) {
// build_name_array();
// }
// if (name_array.length == 0) {
// build_name_array();
// }
// var idx = name_array.findIndex(function(n){return n==name;})
// idx+=1;
// idx %= name_array.length;
// return name_array[idx];
// }
// var idx = name_array.findIndex(function(n){return n==name;})
// idx+=1;
// idx %= name_array.length;
// return name_array[idx];
// }
}
let globalObjectCategory = new ObjectCategory();
export {globalObjectCategory};
export { globalObjectCategory };

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

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

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

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

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

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

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

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

File diff suppressed because it is too large Load Diff

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

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save