Commit 2795f718 authored by bernie wang's avatar bernie wang
Browse files

added recording capabilities to Evaluator

parent 04ce4a31
......@@ -21,6 +21,8 @@
<li><a href="#" class="selected" id="move"><i class="fa material-icons">3d_rotation</i></a></li>
<li><a href="#" id="move2D"><i class="fa fa-arrows"></i></a></li>
<!-- <li><a href="#" id="ids"><i class="fa fa-pencil"></i></a></li> -->
<li>
<button type='button' id='record' style="display: none;">Click to pause recording</button>
<li>
<div>
<table id="object-table">
......@@ -50,13 +52,19 @@
<div id="info">Lidar Annotator</div>
<script src="js/three.min.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/three.min.js"></script>
<script src="js/libs/OrbitControls.js"></script>
<script src="js/libs/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/FileSaver.min.js"></script>
<script src="js/dat.gui.min.js"></script>
<script src="js/libs/FileSaver.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="js/utils.js"></script>
<script src="js/ObjectTable.js"></script>
<script src="js/Box.js?nocache"></script>
<script src="js/Evaluator.js?nocache"></script>
<script src="js/main.js?nocache"></script>
<script type="x-shader/x-vertex" id="vertexshader">
<!-- attribute float size;
......@@ -80,7 +88,6 @@
if ( gl_FragColor.a < ALPHATEST ) discard;
}
</script>
<script src="js/utils.js"></script>
<script src="js/main.js?nocache"></script>
</body>
</html>
\ No newline at end of file
function Evaluator(angle, bounding_boxes) {
this.add_box_count = 0;
this.resize_count = 0;
this.translate_count = 0;
this.rotate_count = 0;
this.delete_count = 0;
this.label_count = 0;
this.rotate_camera_count = 0;
this._3D_timer = new Timer();
this.timer = new Timer();
this.bounding_boxes = bounding_boxes;
this.camera_angle = angle;
this.increment_add_box_count = function() {
this.add_box_count += 1;
};
this.increment_resize_count = function() {
this.resize_count += 1;
};
this.increment_translate_count = function() {
this.translate_count += 1;
};
this.increment_rotate_count = function() {
this.rotate_count += 1;
};
this.increment_delete_count = function() {
this.delete_count += 1;
};
this.increment_label_count = function() {
this.label_count += 1;
};
this.increment_rotate_camera_count = function(angle) {
if (angle != this.camera_angle) {
this.rotate_camera_count += 1;
}
this.camera_angle = angle;
}
this.resume_3D_time = function() {
this._3D_timer.resume();
}
this.pause_3D_time = function() {
this._3D_timer.pause();
}
this.get_3D_time_elapsed = function() {
return this._3D_timer.get_time_elapsed();
}
this.resume_time = function() {
this.timer.resume();
}
this.pause_time = function() {
this.timer.pause();
}
this.get_time_elapsed = function() {
return this.timer.get_time_elapsed();
}
this.pause_recording = function() {
this.pause_time();
if (!move2D) {
this.pause_3D_time();
}
}
this.resume_recording = function() {
this.resume_time();
if (!move2D) {
this.resume_3D_time();
}
}
}
function Timer() {
this.time_elapsed = 0;
this.date = new Date();
this.running = false;
this.resume = function() {
this.date = new Date();
this.running = true;
}
this.pause = function() {
current_time = new Date();
this.time_elapsed += current_time.getTime() - this.date.getTime();
this.state = current_time;
this.running = false;
}
this.get_time_elapsed = function() {
if (this.running) {
this.pause();
this.resume();
}
return this.time_elapsed / 1000;
}
}
\ No newline at end of file
var options = `<select>
<option value="car">Car</option>
<option value="van">Van</option>
<option value="truck">Truck</option>
<option value="pedestrian">Pedestrian</option>
<option value="cyclist">Cyclist</option>
<option value="sitter">Sitter</option>
<option value="tram">Tram</option>
<option value="misc">Misc</option>
/select`;
// method to add row to object id table
function addRow(box) {
$("#object-table tbody").append("<tr><td class='id'>" + box.id + "</td><td>" + options + "</td></tr>");
$("#object-table tbody select").last().focus();
}
// handler that highlights input and corresponding bounding box when input ic selected
$("#object-table").on('mousedown', 'tbody tr', function() {
isMoving = false;
var boxId = $(this).find('.id').text();
var box = getBoxById(boxId);
selectRow(boxId);
selectBox(box, null);
selectedBox = null;
});
// handler that saves input when input is changed
$("#object-table").on('change', 'tbody tr', updateObjectId);
// method to update Box's object id
function updateObjectId() {
var boxId = $(this).find(".id").text();
var input = $(this).find('select').val();
var box = getBoxById(boxId);
box.object_id = input;
evaluator.increment_label_count();
}
// method to get object id table row given id
function getRow(id) {
var row = $("#object-table tbody").find('td').filter(function() {
return $(this).text() == id.toString();}).closest("tr");
return row;
}
// method to select row of object id table given ids
function selectRow(id) {
var row = getRow(id);
$(row).find('select').get(0).focus();
}
// gets box given its id
function getBoxById(id) {
for (var i = 0; i < boundingBoxes.length; i++) {
if (boundingBoxes[i].id == id) {
return boundingBoxes[i];
}
}
}
\ No newline at end of file
......@@ -42,7 +42,9 @@ var isRotating = false;
var grid;
var pointMaterial = new THREE.PointsMaterial( { size: pointSize * 4, sizeAttenuation: false, vertexColors: THREE.VertexColors } );
var evaluator;
var yCoords = [];
var isRecording = false;
init();
var id = 0;
......@@ -161,6 +163,8 @@ function init() {
//
controls = new THREE.OrbitControls( camera, renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
document.getElementById('container').addEventListener( 'mousemove', onDocumentMouseMove, false );
document.getElementById('container').addEventListener( 'mousedown', onDocumentMouseDown, false );
......@@ -172,37 +176,58 @@ function init() {
document.getElementById( 'file_input' ).addEventListener( 'change', upload_file, false );
document.addEventListener("keydown", onKeyDown); //or however you are calling your method
document.addEventListener("keyup", onKeyUp);
document.getElementById( 'record' ).addEventListener( 'click', toggleRecord, false );
}
function toggleRecord(event) {
// pause recording
if (isRecording) {
$("#record").text("Click to resume recording");
evaluator.pause_recording();
move2DMode(event);
isRecording = false;
} else {
// resume recording
isRecording = true;
$("#record").text("Click to pause recording");
evaluator.resume_recording();
}
}
// controller for pressing hotkeys
function onKeyDown(event) {
if (event.ctrlKey) {
toggleControl(false);
}
var KeyID = event.keyCode;
switch(KeyID)
{
case 8: // backspace
deleteSelectedBox();
break;
case 46: // delete
deleteSelectedBox();
break;
case 68:
default:
break;
}
if (isRecording) {
if (event.ctrlKey) {
toggleControl(false);
}
var KeyID = event.keyCode;
switch(KeyID)
{
case 8: // backspace
deleteSelectedBox();
break;
case 46: // delete
deleteSelectedBox();
break;
case 68:
default:
break;
}
}
}
// controller for releasing hotkeys
function onKeyUp(event) {
var KeyID = event.keyCode;
switch(KeyID)
{
default:
toggleControl(true);
break;
}
if(isRecording) {
var KeyID = event.keyCode;
switch(KeyID)
{
default:
toggleControl(true);
break;
}
}
}
// toggles between move2D and move3D
......@@ -242,7 +267,7 @@ function deleteSelectedBox() {
break;
}
}
evaluator.increment_delete_count();
// removes selected box
selectedBox = null;
}
......@@ -265,49 +290,50 @@ function updateMouse( event ) {
// controller for resizing, rotating, translating, or hovering boxes and points
function onDocumentMouseMove( event ) {
event.preventDefault();
if (isRecording) {
if (mouseDown == true) {
var cursor = get3DCoord();
if (mouseDown == true) {
var cursor = get3DCoord();
if (isRotating) {
if (isRotating) {
rotateBox(rotatingBox, cursor);
rotateBox(rotatingBox, cursor);
} else if (isResizing) {
} else if (isResizing) {
// cursor's y coordinate nudged to make bounding box matrix invertible
cursor.y -= 0.00001;
// cursor's y coordinate nudged to make bounding box matrix invertible
cursor.y -= 0.00001;
resize(resizeBox, cursor);
resize(resizeBox, cursor);
} else if (isMoving) {
} else if (isMoving) {
moveBox(selectedBox, cursor);
changeBoundingBoxColor(selectedBox, new THREE.Color( 0,0,7 ));
moveBox(selectedBox, cursor);
changeBoundingBoxColor(selectedBox, new THREE.Color( 0,0,7 ));
} else {
} else {
// if we are initoally drawing a new bounding box,
// we would like to add it to the scene
if (newBox != null && !newBox.added) {
scene.add(newBox.points);
scene.add( newBox.boxHelper );
newBox.added = true;
}
// if we are initoally drawing a new bounding box,
// we would like to add it to the scene
if (newBox != null && !newBox.added) {
scene.add(newBox.points);
scene.add( newBox.boxHelper );
newBox.added = true;
}
resize(newBox, cursor);
resize(newBox, cursor);
}
}
}
var cursor = getCurrentPosition();
if (!controls.enabled) {
// highlights all hover boxes that intersect with cursor
updateHoverBoxes(cursor);
var cursor = getCurrentPosition();
if (!controls.enabled) {
// highlights all hover boxes that intersect with cursor
updateHoverBoxes(cursor);
// highlights closest corner point that intersects with cursor
highlightCorners();
}
// highlights closest corner point that intersects with cursor
highlightCorners();
}
}
}
......@@ -346,74 +372,39 @@ function updateHoverBoxes(v) {
// method to add row to object id table
function addRow(box) {
$("#object-table tbody").append("<tr><td class='id'>" + box.id + "</td><td><input type=text>" + "</input></td></tr>");
$("#object-table tbody input").last().focus();
}
// handler that highlights input and corresponding bounding box when input ic selected
$("#object-table").on('mousedown', 'tbody tr', function() {
isMoving = false;
var boxId = $(this).find('.id').text();
var box = getBoxById(boxId);
selectRow(boxId);
selectBox(box, null);
selectedBox = null;
});
// handler that saves input when input is changed
$("#object-table").on('change paste keyup', 'tbody tr', updateObjectId);
// method to update Box's object id
function updateObjectId() {
var boxId = $(this).find(".id").text();
var input = $(this).find('input').val();
var box = getBoxById(boxId);
box.object_id = input;
}
// method to get object id table row given id
function getRow(id) {
var row = $("#object-table tbody").find('td').filter(function() {
return $(this).text() == id.toString();}).closest("tr");
return row;
}
// method to select row of object id table given ids
function selectRow(id) {
var row = getRow(id);
$('#object-table').find('input').attr('disabled','disabled');
$(row).find('input').removeAttr('disabled');
$(row).find('input').get(0).focus();
}
// gets box given its id
function getBoxById(id) {
for (var i = 0; i < boundingBoxes.length; i++) {
if (boundingBoxes[i].id == id) {
return boundingBoxes[i];
}
}
}
var camera_angle;
// controller for adding box
function onDocumentMouseUp( event ) {
event.preventDefault();
mouseDown = false;
if (newBox != null && newBox.added) {
addBox(newBox);
if (isRecording) {
mouseDown = false;
if (newBox != null && newBox.added) {
addBox(newBox);
evaluator.increment_add_box_count();
}
newBox = null;
if (isResizing) {
evaluator.increment_resize_count();
}
if (isMoving && selectedBox) {
evaluator.increment_translate_count();
}
if (isRotating) {
evaluator.increment_rotate_count();
}
isResizing = false;
isRotating = false;
// if (isMoving) {
// changeBoundingBoxColor(hoverBoxes[0], new THREE.Color( 7,0,0 ));
// }
isMoving = false;
if (move2D) {
evaluator.increment_rotate_camera_count(camera.rotation.z);
}
}
newBox = null;
isResizing = false;
isRotating = false;
// if (isMoving) {
// changeBoundingBoxColor(hoverBoxes[0], new THREE.Color( 7,0,0 ));
// }
isMoving = false;
}
function onDocumentMouseDown( event ) {
......@@ -423,46 +414,48 @@ function onDocumentMouseDown( event ) {
// console.log(camera.rotation.z);
// grid.rotation.y = camera.rotation.z;
// }
if (!controls.enabled) {
mouseDown = true;
anchor = get3DCoord();
var intersection = intersectWithCorner();
// console.log("intersection: ", intersection);
// update hover box
if (selectedBox && (hoverBoxes.length == 0 || hoverBoxes[0] != selectedBox)) {
changeBoundingBoxColor(selectedBox, 0xffff00);
selectedBox = null;
isMoving = false;
}
if (isRecording) {
if (!controls.enabled) {
mouseDown = true;
anchor = get3DCoord();
var intersection = intersectWithCorner();
// console.log("intersection: ", intersection);
// update hover box
if (selectedBox && (hoverBoxes.length == 0 || hoverBoxes[0] != selectedBox)) {
changeBoundingBoxColor(selectedBox, 0xffff00);
selectedBox = null;
isMoving = false;
}
if (intersection != null) {
var box = intersection[0];
var closestIdx = closestPoint(anchor, box.geometry.vertices);
// console.log("closest: ", closestIdx);
if (closestIdx == 4) {
isRotating = true;
rotatingBox = box;
} else {
isResizing = true;
resizeBox = box;
resizeBox.anchor = resizeBox.geometry.vertices[getOppositeCorner(closestIdx)].clone();
}
} else if (hoverBoxes.length == 1) {
isMoving = true;
selectBox(hoverBoxes[0], get3DCoord());
selectRow(selectedBox.id);
if (intersection != null) {
var box = intersection[0];
var closestIdx = closestPoint(anchor, box.geometry.vertices);
// console.log("closest: ", closestIdx);
if (closestIdx == 4) {
isRotating = true;
rotatingBox = box;
} else {
isResizing = true;
resizeBox = box;
resizeBox.anchor = resizeBox.geometry.vertices[getOppositeCorner(closestIdx)].clone();
angle = camera.rotation.z;
var v = anchor.clone();
anchor.x += .000001;
anchor.y -= .000001;
anchor.z += .000001;
newBoundingBox = new THREE.Box3(anchor, v);
newBoxHelper = new THREE.Box3Helper( newBoundingBox, 0xffff00 );
anchor = anchor.clone();
newBox = new Box(anchor, v, angle, newBoundingBox, newBoxHelper);
}
} else if (hoverBoxes.length == 1) {
isMoving = true;
selectBox(hoverBoxes[0], get3DCoord());
selectRow(selectedBox.id);
} else {
angle = camera.rotation.z;
var v = anchor.clone();
anchor.x += .000001;
anchor.y -= .000001;
anchor.z += .000001;
newBoundingBox = new THREE.Box3(anchor, v);
newBoxHelper = new THREE.Box3Helper( newBoundingBox, 0xffff00 );
anchor = anchor.clone();
newBox = new Box(anchor, v, angle, newBoundingBox, newBoxHelper);
}
}
}
......@@ -524,34 +517,53 @@ function generatePointCloudForCluster() {
function moveMode( event ) {
event.preventDefault();
controls.enabled = true;
move2D = false;
// document.getElementById( 'label' ).className = "";
document.getElementById( 'move2D' ).className = "";
document.getElementById( 'move' ).className = "selected";
controls.maxPolarAngle = 2 * Math.PI;
controls.minPolarAngle = -2 * Math.PI;
unprojectFromXZ();
assertRecordMode();