mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 04:44:08 +02:00
Merge pull request #7173 from ericrius1/whiteboardV2
Whiteboard using markers and erasers
This commit is contained in:
commit
ae824bb180
3 changed files with 582 additions and 0 deletions
examples/homeContent/whiteboardV2
109
examples/homeContent/whiteboardV2/eraserEntityScript.js
Normal file
109
examples/homeContent/whiteboardV2/eraserEntityScript.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// eraserEntityScript.js
|
||||
// examples/homeContent/eraserEntityScript
|
||||
//
|
||||
// Created by Eric Levin on 2/17/15.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This entity script provides logic for an object with attached script to erase nearby marker strokes
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
Script.include("../../libraries/utils.js");
|
||||
var TRIGGER_CONTROLS = [
|
||||
Controller.Standard.LT,
|
||||
Controller.Standard.RT,
|
||||
];
|
||||
var _this;
|
||||
Eraser = function() {
|
||||
_this = this;
|
||||
|
||||
_this.ERASER_TRIGGER_THRESHOLD = 0.2;
|
||||
_this.STROKE_NAME = "hifi-marker-stroke";
|
||||
_this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.7;
|
||||
_this.ERASER_RESET_WAIT_TIME = 3000;
|
||||
};
|
||||
|
||||
Eraser.prototype = {
|
||||
|
||||
startEquip: function(id, params) {
|
||||
_this.equipped = true;
|
||||
_this.hand = params[0] == "left" ? 0 : 1;
|
||||
// We really only need to grab position of marker strokes once, and then just check to see if eraser comes near enough to those strokes
|
||||
Overlays.editOverlay(_this.searchSphere, {
|
||||
visible: true
|
||||
});
|
||||
},
|
||||
continueEquip: function() {
|
||||
_this.eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position;
|
||||
Overlays.editOverlay(_this.searchSphere, {
|
||||
position: _this.eraserPosition
|
||||
});
|
||||
this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]);
|
||||
if (_this.triggerValue > _this.ERASER_TRIGGER_THRESHOLD) {
|
||||
_this.continueHolding();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
continueHolding: function() {
|
||||
var strokeIDs = Entities.findEntities(_this.eraserPosition, _this.ERASER_TO_STROKE_SEARCH_RADIUS);
|
||||
// Create a map of stroke entities and their positions
|
||||
|
||||
strokeIDs.forEach(function(strokeID) {
|
||||
var strokeProps = Entities.getEntityProperties(strokeID, ["position", "name"]);
|
||||
if (strokeProps.name === _this.STROKE_NAME && Vec3.distance(_this.eraserPosition, strokeProps.position) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) {
|
||||
Entities.deleteEntity(strokeID);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
releaseEquip: function() {
|
||||
Overlays.editOverlay(_this.searchSphere, {
|
||||
visible: false
|
||||
});
|
||||
|
||||
// Once user releases eraser, wait a bit then put marker back to its original position and rotation
|
||||
Script.setTimeout(function() {
|
||||
var userData = getEntityUserData(_this.entityID);
|
||||
Entities.editEntity(_this.entityID, {
|
||||
position: userData.originalPosition,
|
||||
rotation: userData.originalRotation,
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -0.01,
|
||||
z: 0
|
||||
}
|
||||
});
|
||||
}, _this.ERASER_RESET_WAIT_TIME);
|
||||
},
|
||||
|
||||
|
||||
|
||||
preload: function(entityID) {
|
||||
_this.entityID = entityID;
|
||||
_this.searchSphere = Overlays.addOverlay('sphere', {
|
||||
size: _this.ERASER_TO_STROKE_SEARCH_RADIUS,
|
||||
color: {
|
||||
red: 200,
|
||||
green: 10,
|
||||
blue: 10
|
||||
},
|
||||
alpha: 0.2,
|
||||
solid: true,
|
||||
visible: false
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
unload: function() {
|
||||
Overlays.deleteOverlay(_this.searchSphere);
|
||||
}
|
||||
};
|
||||
|
||||
// entity scripts always need to return a newly constructed object of our type
|
||||
return new Eraser();
|
||||
});
|
219
examples/homeContent/whiteboardV2/markerEntityScript.js
Normal file
219
examples/homeContent/whiteboardV2/markerEntityScript.js
Normal file
|
@ -0,0 +1,219 @@
|
|||
//
|
||||
// markerTipEntityScript.js
|
||||
// examples/homeContent/markerTipEntityScript
|
||||
//
|
||||
// Created by Eric Levin on 2/17/15.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This script provides the logic for an object to draw marker strokes on its associated whiteboard
|
||||
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
Script.include("../../libraries/utils.js");
|
||||
var TRIGGER_CONTROLS = [
|
||||
Controller.Standard.LT,
|
||||
Controller.Standard.RT,
|
||||
];
|
||||
var MAX_POINTS_PER_STROKE = 40;
|
||||
var _this;
|
||||
MarkerTip = function() {
|
||||
_this = this;
|
||||
_this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png";
|
||||
_this.strokeForwardOffset = 0.0001;
|
||||
_this.STROKE_WIDTH_RANGE = {
|
||||
min: 0.002,
|
||||
max: 0.01
|
||||
};
|
||||
_this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4;
|
||||
_this.MIN_DISTANCE_BETWEEN_POINTS = 0.002;
|
||||
_this.MAX_DISTANCE_BETWEEN_POINTS = 0.1;
|
||||
_this.strokes = [];
|
||||
_this.PAINTING_TRIGGER_THRESHOLD = 0.2;
|
||||
_this.STROKE_NAME = "hifi-marker-stroke";
|
||||
_this.WHITEBOARD_SURFACE_NAME = "hifi-whiteboardDrawingSurface";
|
||||
_this.MARKER_RESET_WAIT_TIME = 3000;
|
||||
};
|
||||
|
||||
MarkerTip.prototype = {
|
||||
|
||||
startEquip: function(id, params) {
|
||||
_this.whiteboards = [];
|
||||
_this.equipped = true;
|
||||
_this.hand = params[0] == "left" ? 0 : 1;
|
||||
_this.markerColor = getEntityUserData(_this.entityID).markerColor;
|
||||
// search for whiteboards
|
||||
var markerPosition = Entities.getEntityProperties(_this.entityID, "position").position;
|
||||
var entities = Entities.findEntities(markerPosition, 10);
|
||||
entities.forEach(function(entity) {
|
||||
var entityName = Entities.getEntityProperties(entity, "name").name;
|
||||
if (entityName === _this.WHITEBOARD_SURFACE_NAME) {
|
||||
|
||||
_this.whiteboards.push(entity);
|
||||
}
|
||||
});
|
||||
|
||||
print("intersectable entities " + JSON.stringify(_this.whiteboards))
|
||||
},
|
||||
|
||||
releaseEquip: function() {
|
||||
_this.resetStroke();
|
||||
Overlays.editOverlay(_this.laserPointer, {
|
||||
visible: false
|
||||
});
|
||||
|
||||
// Once user releases marker, wait a bit then put marker back to its original position and rotation
|
||||
Script.setTimeout(function() {
|
||||
var userData = getEntityUserData(_this.entityID);
|
||||
Entities.editEntity(_this.entityID, {
|
||||
position: userData.originalPosition,
|
||||
rotation: userData.originalRotation,
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -0.01,
|
||||
z: 0
|
||||
}
|
||||
});
|
||||
}, _this.MARKER_RESET_WAIT_TIME);
|
||||
},
|
||||
|
||||
|
||||
continueEquip: function() {
|
||||
// cast a ray from marker and see if it hits anything
|
||||
var markerProps = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]);
|
||||
|
||||
var pickRay = {
|
||||
origin: markerProps.position,
|
||||
direction: Quat.getFront(markerProps.rotation)
|
||||
}
|
||||
var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards);
|
||||
|
||||
if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) {
|
||||
_this.currentWhiteboard = intersection.entityID;
|
||||
var whiteboardRotation = Entities.getEntityProperties(_this.currentWhiteboard, "rotation").rotation;
|
||||
_this.whiteboardNormal = Quat.getFront(whiteboardRotation);
|
||||
Overlays.editOverlay(_this.laserPointer, {
|
||||
visible: true,
|
||||
position: intersection.intersection,
|
||||
rotation: whiteboardRotation
|
||||
})
|
||||
_this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]);
|
||||
if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) {
|
||||
_this.paint(intersection.intersection)
|
||||
} else {
|
||||
_this.resetStroke();
|
||||
}
|
||||
} else {
|
||||
if (_this.currentStroke) {
|
||||
_this.resetStroke();
|
||||
}
|
||||
|
||||
Overlays.editOverlay(_this.laserPointer, {
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
newStroke: function(position) {
|
||||
_this.strokeBasePosition = position;
|
||||
_this.currentStroke = Entities.addEntity({
|
||||
type: "PolyLine",
|
||||
name: _this.STROKE_NAME,
|
||||
dimensions: {
|
||||
x: 10,
|
||||
y: 10,
|
||||
z: 10
|
||||
},
|
||||
position: position,
|
||||
textures: _this.MARKER_TEXTURE_URL,
|
||||
color: _this.markerColor,
|
||||
lifetime: 5000,
|
||||
});
|
||||
|
||||
_this.linePoints = [];
|
||||
_this.normals = [];
|
||||
_this.strokes.push(_this.currentStroke);
|
||||
},
|
||||
|
||||
paint: function(position) {
|
||||
var basePosition = position;
|
||||
if (!_this.currentStroke) {
|
||||
if (_this.oldPosition) {
|
||||
basePosition = _this.oldPosition;
|
||||
}
|
||||
_this.newStroke(basePosition);
|
||||
}
|
||||
|
||||
var localPoint = Vec3.subtract(basePosition, _this.strokeBasePosition);
|
||||
localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset));
|
||||
|
||||
if (_this.linePoints.length > 0) {
|
||||
var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length - 1]);
|
||||
if (distance < _this.MIN_DISTANCE_BETWEEN_POINTS) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_this.linePoints.push(localPoint);
|
||||
_this.normals.push(_this.whiteboardNormal);
|
||||
|
||||
var strokeWidths = [];
|
||||
for (var i = 0; i < _this.linePoints.length; i++) {
|
||||
// Create a temp array of stroke widths for calligraphy effect - start and end should be less wide
|
||||
var pointsFromCenter = Math.abs(_this.linePoints.length / 2 - i);
|
||||
var pointWidth = map(pointsFromCenter, 0, this.linePoints.length / 2, _this.STROKE_WIDTH_RANGE.max, this.STROKE_WIDTH_RANGE.min);
|
||||
strokeWidths.push(pointWidth);
|
||||
}
|
||||
|
||||
Entities.editEntity(_this.currentStroke, {
|
||||
linePoints: _this.linePoints,
|
||||
normals: _this.normals,
|
||||
strokeWidths: strokeWidths
|
||||
});
|
||||
|
||||
if (_this.linePoints.length > MAX_POINTS_PER_STROKE) {
|
||||
Entities.editEntity(_this.currentStroke, {
|
||||
parentID: _this.currentWhiteboard
|
||||
});
|
||||
_this.currentStroke = null;
|
||||
_this.oldPosition = position;
|
||||
}
|
||||
},
|
||||
resetStroke: function() {
|
||||
|
||||
Entities.editEntity(_this.currentStroke, {
|
||||
parentID: _this.currentWhiteboard
|
||||
});
|
||||
_this.currentStroke = null;
|
||||
|
||||
_this.oldPosition = null;
|
||||
},
|
||||
|
||||
preload: function(entityID) {
|
||||
this.entityID = entityID;
|
||||
_this.laserPointer = Overlays.addOverlay("circle3d", {
|
||||
color: {
|
||||
red: 220,
|
||||
green: 35,
|
||||
blue: 53
|
||||
},
|
||||
solid: true,
|
||||
size: 0.01,
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
unload: function() {
|
||||
Overlays.deleteOverlay(_this.laserPointer);
|
||||
_this.strokes.forEach(function(stroke) {
|
||||
Entities.deleteEntity(stroke);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// entity scripts always need to return a newly constructed object of our type
|
||||
return new MarkerTip();
|
||||
});
|
254
examples/homeContent/whiteboardV2/whiteboardSpawner.js
Normal file
254
examples/homeContent/whiteboardV2/whiteboardSpawner.js
Normal file
|
@ -0,0 +1,254 @@
|
|||
//
|
||||
// whiteboardSpawner.js
|
||||
// examples/homeContent/whiteboardV2
|
||||
//
|
||||
// Created by Eric Levina on 2/17/16
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Run this script to spawn a whiteboard, markers, and an eraser.
|
||||
// To draw on the whiteboard, equip a marker and hold down trigger with marker tip pointed at whiteboard
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
Script.include("../../libraries/utils.js")
|
||||
|
||||
var orientation = MyAvatar.orientation;
|
||||
orientation = Quat.safeEulerAngles(orientation);
|
||||
var markerRotation = Quat.fromVec3Degrees({
|
||||
x: orientation.x + 10,
|
||||
y: orientation.y - 90,
|
||||
z: orientation.z
|
||||
})
|
||||
orientation.x = 0;
|
||||
var whiteboardRotation = Quat.fromVec3Degrees({
|
||||
x: 0,
|
||||
y: orientation.y,
|
||||
z: 0
|
||||
});
|
||||
orientation = Quat.fromVec3Degrees(orientation);
|
||||
var markers = [];
|
||||
|
||||
|
||||
var whiteboardPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation)));
|
||||
var WHITEBOARD_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/Whiteboard-4.fbx";
|
||||
var WHITEBOARD_COLLISION_HULL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/whiteboardCollisionHull.obj";
|
||||
var whiteboard = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "whiteboard",
|
||||
modelURL: WHITEBOARD_MODEL_URL,
|
||||
position: whiteboardPosition,
|
||||
rotation: whiteboardRotation,
|
||||
shapeType: 'compound',
|
||||
compoundShapeURL: WHITEBOARD_COLLISION_HULL_URL,
|
||||
dimensions: {
|
||||
x: 1.86,
|
||||
y: 2.7,
|
||||
z: 0.4636
|
||||
},
|
||||
});
|
||||
|
||||
var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, {
|
||||
x: 0.0,
|
||||
y: 0.45,
|
||||
z: 0.0
|
||||
});
|
||||
whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(whiteboardRotation)));
|
||||
var moveForwardDistance = 0.02;
|
||||
whiteboardFrontSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-moveForwardDistance, Quat.getFront(whiteboardRotation)));
|
||||
var whiteboardSurfaceSettings = {
|
||||
type: "Box",
|
||||
name: "hifi-whiteboardDrawingSurface",
|
||||
dimensions: {
|
||||
x: 1.82,
|
||||
y: 1.8,
|
||||
z: 0.01
|
||||
},
|
||||
color: {
|
||||
red: 200,
|
||||
green: 10,
|
||||
blue: 200
|
||||
},
|
||||
position: whiteboardFrontSurfacePosition,
|
||||
rotation: whiteboardRotation,
|
||||
visible: false,
|
||||
parentID: whiteboard
|
||||
}
|
||||
var whiteboardFrontDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings);
|
||||
|
||||
|
||||
whiteboardBackSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(moveForwardDistance, Quat.getFront(whiteboardRotation)));
|
||||
whiteboardSurfaceSettings.position = whiteboardBackSurfacePosition;
|
||||
|
||||
var whiteboardBackDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings);
|
||||
|
||||
|
||||
var WHITEBOARD_RACK_DEPTH = 1.9;
|
||||
|
||||
var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser-2.fbx";
|
||||
var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js?v43");
|
||||
var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(whiteboardRotation)));
|
||||
eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getRight(whiteboardRotation)));
|
||||
var eraserRotation = markerRotation;
|
||||
|
||||
var eraser = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: ERASER_MODEL_URL,
|
||||
position: eraserPosition,
|
||||
script: ERASER_SCRIPT_URL,
|
||||
shapeType: "box",
|
||||
dimensions: {
|
||||
x: 0.0858,
|
||||
y: 0.0393,
|
||||
z: 0.2083
|
||||
},
|
||||
rotation: eraserRotation,
|
||||
dynamic: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -1,
|
||||
z: 0
|
||||
},
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -0.1,
|
||||
z: 0
|
||||
},
|
||||
userData: JSON.stringify({
|
||||
originalPosition: eraserPosition,
|
||||
originalRotation: eraserRotation,
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.020,
|
||||
y: 0.120,
|
||||
z: 0.049
|
||||
}, {
|
||||
x: 0.1004,
|
||||
y: 0.6424,
|
||||
z: 0.717,
|
||||
w: 0.250
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: -0.005,
|
||||
y: 0.1101,
|
||||
z: 0.053
|
||||
}, {
|
||||
x: 0.723,
|
||||
y: 0.289,
|
||||
z: 0.142,
|
||||
w: 0.610
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
createMarkers();
|
||||
|
||||
function createMarkers() {
|
||||
var modelURLS = [
|
||||
"https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-blue.fbx",
|
||||
"https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-red.fbx",
|
||||
"https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-black.fbx",
|
||||
];
|
||||
|
||||
var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation)));
|
||||
|
||||
createMarker(modelURLS[0], markerPosition, {
|
||||
red: 10,
|
||||
green: 10,
|
||||
blue: 200
|
||||
});
|
||||
|
||||
markerPosition = Vec3.sum(markerPosition, Vec3.multiply(-0.2, Quat.getFront(markerRotation)));
|
||||
createMarker(modelURLS[1], markerPosition, {
|
||||
red: 200,
|
||||
green: 10,
|
||||
blue: 10
|
||||
});
|
||||
|
||||
markerPosition = Vec3.sum(markerPosition, Vec3.multiply(0.4, Quat.getFront(markerRotation)));
|
||||
createMarker(modelURLS[2], markerPosition, {
|
||||
red: 10,
|
||||
green: 10,
|
||||
blue: 10
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function createMarker(modelURL, markerPosition, markerColor) {
|
||||
var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random());
|
||||
var marker = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: modelURL,
|
||||
rotation: markerRotation,
|
||||
shapeType: "box",
|
||||
name: "marker",
|
||||
dynamic: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -1,
|
||||
z: 0
|
||||
},
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -0.1,
|
||||
z: 0
|
||||
},
|
||||
position: markerPosition,
|
||||
dimensions: {
|
||||
x: 0.027,
|
||||
y: 0.027,
|
||||
z: 0.164
|
||||
},
|
||||
name: "marker",
|
||||
script: MARKER_SCRIPT_URL,
|
||||
userData: JSON.stringify({
|
||||
originalPosition: markerPosition,
|
||||
originalRotation: markerRotation,
|
||||
markerColor: markerColor,
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.001,
|
||||
y: 0.139,
|
||||
z: 0.050
|
||||
}, {
|
||||
x: -0.73,
|
||||
y: -0.043,
|
||||
z: -0.108,
|
||||
w: -0.666
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.007,
|
||||
y: 0.151,
|
||||
z: 0.061
|
||||
}, {
|
||||
x: -0.417,
|
||||
y: 0.631,
|
||||
z: -0.389,
|
||||
w: -0.525
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
markers.push(marker);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(whiteboard);
|
||||
Entities.deleteEntity(whiteboardFrontDrawingSurface);
|
||||
Entities.deleteEntity(whiteboardBackDrawingSurface);
|
||||
Entities.deleteEntity(eraser);
|
||||
markers.forEach(function(marker) {
|
||||
Entities.deleteEntity(marker);
|
||||
});
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
Loading…
Reference in a new issue