mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-10 04:38:57 +02:00
234 lines
No EOL
8.3 KiB
JavaScript
234 lines
No EOL
8.3 KiB
JavaScript
//
|
|
// whiteBoardEntityScript.js
|
|
// examples/painting/whiteboard
|
|
//
|
|
// Created by Eric Levin on 10/12/15.
|
|
// Copyright 2015 High Fidelity, Inc.
|
|
//
|
|
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
|
|
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */
|
|
|
|
/*global Whiteboard */
|
|
|
|
|
|
|
|
(function() {
|
|
Script.include("../../libraries/utils.js");
|
|
var _this;
|
|
var RIGHT_HAND = 1;
|
|
var LEFT_HAND = 0;
|
|
var MIN_POINT_DISTANCE = 0.02;
|
|
var MAX_POINT_DISTANCE = 0.5;
|
|
var MAX_POINTS_PER_LINE = 40;
|
|
var MAX_DISTANCE = 5;
|
|
|
|
var PAINT_TRIGGER_THRESHOLD = 0.6;
|
|
var MIN_STROKE_WIDTH = 0.0005;
|
|
var MAX_STROKE_WIDTH = 0.03;
|
|
|
|
Whiteboard = function() {
|
|
_this = this;
|
|
};
|
|
|
|
Whiteboard.prototype = {
|
|
|
|
setRightHand: function() {
|
|
this.hand = RIGHT_HAND;
|
|
},
|
|
|
|
setLeftHand: function() {
|
|
this.hand = LEFT_HAND;
|
|
},
|
|
|
|
startFarGrabNonColliding: function() {
|
|
if (this.painting) {
|
|
return;
|
|
}
|
|
if (this.hand === RIGHT_HAND) {
|
|
this.getHandPosition = MyAvatar.getRightPalmPosition;
|
|
this.getHandRotation = MyAvatar.getRightPalmRotation;
|
|
this.triggerAction = Controller.findAction("RIGHT_HAND_CLICK");
|
|
} else if (this.hand === LEFT_HAND) {
|
|
this.getHandPosition = MyAvatar.getLeftPalmPosition;
|
|
this.getHandRotation = MyAvatar.getLeftPalmRotation;
|
|
this.triggerAction = Controller.findAction("LEFT_HAND_CLICK");
|
|
}
|
|
Overlays.editOverlay(this.laserPointer, {
|
|
visible: true
|
|
});
|
|
},
|
|
|
|
continueFarGrabbingNonColliding: function() {
|
|
var handPosition = this.getHandPosition();
|
|
var pickRay = {
|
|
origin: handPosition,
|
|
direction: Quat.getUp(this.getHandRotation())
|
|
};
|
|
|
|
this.intersection = Entities.findRayIntersection(pickRay, true, this.whitelist);
|
|
|
|
if (this.intersection.intersects) {
|
|
var distance = Vec3.distance(handPosition, this.intersection.intersection);
|
|
if (distance < MAX_DISTANCE) {
|
|
this.triggerValue = Controller.getActionValue(this.triggerAction);
|
|
this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH);
|
|
var displayPoint = this.intersection.intersection;
|
|
displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, -0.01));
|
|
Overlays.editOverlay(this.laserPointer, {
|
|
position: displayPoint,
|
|
size: {
|
|
x: this.currentStrokeWidth,
|
|
y: this.currentStrokeWidth
|
|
}
|
|
});
|
|
if (this.triggerValue > PAINT_TRIGGER_THRESHOLD) {
|
|
this.paint(this.intersection.intersection, this.intersection.surfaceNormal);
|
|
} else {
|
|
this.painting = false;
|
|
this.oldPosition = null;
|
|
}
|
|
}
|
|
} else if(this.intersection.properties.type !== "Unknown") {
|
|
//If type is unknown, ignore
|
|
print("entity name " + this.intersection.properties.type);
|
|
this.stopPainting();
|
|
}
|
|
},
|
|
|
|
stopPainting: function() {
|
|
this.painting = false;
|
|
Overlays.editOverlay(this.laserPointer, {
|
|
visible: false
|
|
});
|
|
this.oldPosition = null;
|
|
print("STOP PAINTING");
|
|
},
|
|
|
|
paint: function(position, normal) {
|
|
if (this.painting === false) {
|
|
if (this.oldPosition) {
|
|
this.newStroke(this.oldPosition);
|
|
} else {
|
|
this.newStroke(position);
|
|
}
|
|
this.painting = true;
|
|
}
|
|
|
|
|
|
var localPoint = Vec3.subtract(position, this.strokeBasePosition);
|
|
//Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on
|
|
localPoint = Vec3.sum(localPoint, Vec3.multiply(this.normal, 0.001 + Math.random() * 0.001)); //rand avoid z fighting
|
|
var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]);
|
|
if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) {
|
|
//need a minimum distance to avoid binormal NANs
|
|
|
|
return;
|
|
}
|
|
if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) {
|
|
//Prevents drawing lines accross models
|
|
this.painting = false;
|
|
return;
|
|
}
|
|
if (this.strokePoints.length === 0) {
|
|
localPoint = {
|
|
x: 0,
|
|
y: 0,
|
|
z: 0
|
|
};
|
|
}
|
|
|
|
this.strokePoints.push(localPoint);
|
|
this.strokeNormals.push(this.normal);
|
|
this.strokeWidths.push(this.currentStrokeWidth);
|
|
Entities.editEntity(this.currentStroke, {
|
|
linePoints: this.strokePoints,
|
|
normals: this.strokeNormals,
|
|
strokeWidths: this.strokeWidths
|
|
});
|
|
if (this.strokePoints.length === MAX_POINTS_PER_LINE) {
|
|
this.painting = false;
|
|
return;
|
|
}
|
|
this.oldPosition = position;
|
|
},
|
|
|
|
|
|
newStroke: function(position) {
|
|
|
|
this.strokeBasePosition = position;
|
|
this.currentStroke = Entities.addEntity({
|
|
position: position,
|
|
type: "PolyLine",
|
|
name: "paintStroke",
|
|
color: this.strokeColor,
|
|
dimensions: {
|
|
x: 50,
|
|
y: 50,
|
|
z: 50
|
|
},
|
|
lifetime: 200
|
|
});
|
|
this.strokePoints = [];
|
|
this.strokeNormals = [];
|
|
this.strokeWidths = [];
|
|
|
|
this.strokes.push(this.currentStroke);
|
|
|
|
},
|
|
|
|
releaseGrab: function() {
|
|
print("RELEASE");
|
|
this.stopPainting();
|
|
|
|
},
|
|
|
|
changeColor: function() {
|
|
this.strokeColor = JSON.parse(Entities.getEntityProperties(this.entityID, ["userData"]).userData).currentColor;
|
|
Overlays.editOverlay(this.laserPointer, {
|
|
color: this.strokeColor
|
|
});
|
|
},
|
|
|
|
eraseBoard: function() {
|
|
var entities = Entities.findEntities(this.position, 5);
|
|
entities.forEach(function(entity) {
|
|
var name = Entities.getEntityProperties(entity, "name").name;
|
|
if (name === "paintStroke") {
|
|
Entities.deleteEntity(entity);
|
|
}
|
|
});
|
|
},
|
|
|
|
preload: function(entityID) {
|
|
this.entityID = entityID;
|
|
var props = Entities.getEntityProperties(this.entityID, ["position", "rotation", "userData"]);
|
|
this.position = props.position;
|
|
this.rotation = props.rotation;
|
|
this.normal = Vec3.multiply(Quat.getFront(this.rotation), -1);
|
|
this.painting = false;
|
|
this.strokes = [];
|
|
this.whitelist = [this.entityID];
|
|
this.strokeColor = JSON.parse(props.userData).currentColor;
|
|
this.laserPointer = Overlays.addOverlay("circle3d", {
|
|
color: this.strokeColor,
|
|
solid: true,
|
|
rotation: this.rotation
|
|
});
|
|
},
|
|
|
|
unload: function() {
|
|
this.strokes.forEach(function(stroke) {
|
|
Entities.deleteEntity(stroke);
|
|
});
|
|
Overlays.deleteOverlay(this.laserPointer);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
// entity scripts always need to return a newly constructed object of our type
|
|
return new Whiteboard();
|
|
}); |