314 lines
No EOL
13 KiB
JavaScript
314 lines
No EOL
13 KiB
JavaScript
//
|
|
// detectGrabExample.js
|
|
// examples/entityScripts
|
|
//
|
|
// Created by Brad Hefta-Gaub on 9/3/15.
|
|
// Copyright 2015 High Fidelity, Inc.
|
|
//
|
|
// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
(function() {
|
|
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
|
Script.include(HIFI_PUBLIC_BUCKET + "scripts/libraries/utils.js");
|
|
Script.include(HIFI_PUBLIC_BUCKET + "scripts/libraries/overlayManager.js");
|
|
//Script.include("C:\\Users\\Proprietario\\Desktop\\overlayManager.js"); //doesn't work
|
|
//Script.include('../libraries/overlayManager.js'); //doesn't work
|
|
//Script.include("http://s3.amazonaws.com/hifi-content/alessandro/dev/JS/libraries/overlayManager.js");
|
|
|
|
//var BROWN_ICON_URL = "http://cdn.highfidelity.com/alan/production/icons/ICO_rec-active.svg";
|
|
var BROWN_ICON_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/UI_Brown.svg";
|
|
var RED_ICON_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/UI_Red.svg";
|
|
var BLACK_ICON_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/UI_Black.svg";
|
|
|
|
var ICONS = [
|
|
BROWN_ICON_URL,
|
|
RED_ICON_URL,
|
|
BLACK_ICON_URL
|
|
];
|
|
|
|
var MIN_DIMENSION_THRESHOLD = null;
|
|
var IN_HAND_STATUS = "inHand";
|
|
var IN_INSPECT_STATUS = "inInspect";
|
|
|
|
var RIGHT_HAND = 1;
|
|
var LEFT_HAND = 0;
|
|
|
|
var LINE_LENGTH = 100;
|
|
var COLOR = {
|
|
red: 10,
|
|
green: 10,
|
|
blue: 255
|
|
};
|
|
|
|
var COMFORT_ARM_LENGTH = 0.5;
|
|
|
|
var PENETRATION_THRESHOLD = 0.2;
|
|
|
|
var _this;
|
|
var inspecting = false;
|
|
var isUIWorking = false;
|
|
var inspectingMyItem = false;
|
|
var waitingForBumpReleased = false;
|
|
var rightController = null; //rightController and leftController are two objects
|
|
var leftController = null;
|
|
var zoneID = null;
|
|
var inspectedEntityID = null;
|
|
|
|
var newPosition = null;
|
|
var newRotation = null;
|
|
|
|
var mainPanel = null;
|
|
var buttons = [];
|
|
|
|
|
|
// this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember
|
|
// our this object, so we can access it in cases where we're called without a this (like in the case of various global signals)
|
|
InspectEntity = function() {
|
|
_this = this;
|
|
};
|
|
|
|
|
|
function MyController(hand) {
|
|
print("created hand: " + hand);
|
|
this.hand = hand;
|
|
if (this.hand === RIGHT_HAND) {
|
|
this.getHandPosition = MyAvatar.getRightPalmPosition;
|
|
this.getHandRotation = MyAvatar.getRightPalmRotation;
|
|
this.bumper = Controller.Standard.RB;
|
|
} else {
|
|
this.getHandPosition = MyAvatar.getLeftPalmPosition;
|
|
this.getHandRotation = MyAvatar.getLeftPalmRotation;
|
|
this.bumper = Controller.Standard.LB;
|
|
}
|
|
|
|
this.pickRay = null; // ray object
|
|
this.overlayLine = null; // id of line overlay
|
|
this.waitingForBumpReleased = false;
|
|
|
|
this.overlayLineOn = function(closePoint, farPoint, color) {
|
|
if (this.overlayLine == null) {
|
|
var lineProperties = {
|
|
lineWidth: 5,
|
|
start: closePoint,
|
|
end: farPoint,
|
|
color: color,
|
|
ignoreRayIntersection: true, // ??
|
|
visible: true,
|
|
alpha: 1
|
|
};
|
|
this.overlayLine = new Line3DOverlay(lineProperties);
|
|
} else {
|
|
this.overlayLine.start = closePoint;
|
|
this.overlayLine.end = farPoint;
|
|
}
|
|
},
|
|
|
|
//the update of each hand has to update the ray belonging to that hand and handle the bumper event
|
|
this.updateHand = function() {
|
|
//update the ray object
|
|
this.pickRay = {
|
|
origin: this.getHandPosition(),
|
|
direction: Quat.getUp(this.getHandRotation())
|
|
};
|
|
//update the ray overlay
|
|
this.overlayLineOn(this.pickRay.origin, Vec3.sum(this.pickRay.origin, Vec3.multiply(this.pickRay.direction, LINE_LENGTH)), COLOR);
|
|
|
|
//detect the bumper event
|
|
//manage event on UI
|
|
var bumperPressed = Controller.getValue(this.bumper);
|
|
if (bumperPressed && !this.waitingForBumpReleased) {
|
|
this.waitingForBumpReleased = true;
|
|
var triggeredButton = OverlayManager.findOnRay(this.pickRay);
|
|
if (triggeredButton != null) {
|
|
for (var i = 0; i < buttons.length; i++) {
|
|
if (buttons[i] == triggeredButton) {
|
|
var dataJSON = {
|
|
index: i
|
|
};
|
|
var dataArray = [JSON.stringify(dataJSON)];
|
|
|
|
Entities.callEntityMethod(inspectedEntityID, 'changeModel', dataArray);
|
|
print("ChangeColor by ID: " + i);
|
|
}
|
|
}
|
|
}
|
|
} else if (!bumperPressed && this.waitingForBumpReleased) {
|
|
this.waitingForBumpReleased = false;
|
|
}
|
|
},
|
|
|
|
this.clean = function() {
|
|
this.pickRay = null;
|
|
this.overlayLine.destroy();
|
|
}
|
|
};
|
|
|
|
function update(deltaTime) {
|
|
//the if condition should depend from other stuff
|
|
if (inspecting) {
|
|
//update the rays from both hands
|
|
leftController.updateHand();
|
|
rightController.updateHand();
|
|
|
|
//check the item status for consistency
|
|
var entityStatus = getEntityCustomData('statusKey', inspectedEntityID, null).status;
|
|
if (entityStatus == IN_HAND_STATUS) {
|
|
//the inspection is over
|
|
inspecting = false;
|
|
inspectedEntityID = null;
|
|
}
|
|
} else if (isUIWorking) {
|
|
//clean all the UI stuff
|
|
// Destroy rays
|
|
leftController.clean();
|
|
rightController.clean();
|
|
// Destroy overlay
|
|
mainPanel.destroy();
|
|
isUIWorking = false;
|
|
}
|
|
|
|
_this.positionRotationUpdate();
|
|
};
|
|
|
|
InspectEntity.prototype = {
|
|
|
|
preload: function(entityID) {
|
|
this.entityID = entityID;
|
|
print("PRELOAD INSPECT ENTITY");
|
|
//get the owner ID from user data and compare to the mine
|
|
//the update will be connected just for the owner
|
|
var ownerObj = getEntityCustomData('ownerKey', this.entityID, null);
|
|
if (ownerObj.ownerID === MyAvatar.sessionUUID) {
|
|
rightController = new MyController(RIGHT_HAND); //rightController and leftController are two objects
|
|
leftController = new MyController(LEFT_HAND);
|
|
inspectingMyItem = true;
|
|
inspectRadius = (Entities.getEntityProperties(_this.entityID).dimensions.x) / 2 + COMFORT_ARM_LENGTH;
|
|
Script.update.connect(update);
|
|
}
|
|
},
|
|
|
|
doSomething: function (entityID, dataArray) {
|
|
var data = JSON.parse(dataArray[0]);
|
|
var itemOwnerObj = getEntityCustomData('ownerKey', data.id, null);
|
|
//print("------- The owner of the item is: " + ((itemOwnerObj == null) ? itemOwnerObj : itemOwnerObj.ownerID));
|
|
//print("item ID: " + data.id);
|
|
|
|
var inspectOwnerObj = getEntityCustomData('ownerKey', this.entityID, null);
|
|
//print("------- The owner of the inspectZone is: " + ((inspectOwnerObj == null) ? inspectOwnerObj : inspectOwnerObj.ownerID));
|
|
//print("zone ID: " + this.entityID);
|
|
|
|
if (inspectOwnerObj == null) {
|
|
//print("The inspectZone doesn't have a owner.");
|
|
Entities.deleteEntity(data.id);
|
|
}
|
|
|
|
if (itemOwnerObj.ownerID === inspectOwnerObj.ownerID) {
|
|
//setup the things for inspecting the item
|
|
inspecting = true;
|
|
inspectedEntityID = data.id; //store the ID of the inspected entity
|
|
setEntityCustomData('statusKey', data.id, {
|
|
status: IN_INSPECT_STATUS
|
|
});
|
|
//print("Set status!");
|
|
|
|
_this.createInspectUI();
|
|
|
|
Entities.editEntity(_this.entityID, { visible: false });
|
|
|
|
} else {
|
|
//print("Not your inspect zone!");
|
|
Entities.deleteEntity(data.id);
|
|
}
|
|
},
|
|
|
|
positionRotationUpdate: function() {
|
|
//position
|
|
newPosition = Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.getOrientation()), inspectRadius));
|
|
Entities.editEntity(_this.entityID, { position: newPosition });
|
|
|
|
newRotation = Camera.getOrientation();
|
|
Entities.editEntity(_this.entityID, { rotation: newRotation });
|
|
},
|
|
|
|
createInspectUI : function() {
|
|
//print ("Creating UI");
|
|
|
|
//set the main panel to follow the inspect entity
|
|
mainPanel = new OverlayPanel({
|
|
anchorPositionBinding: { entity: _this.entityID },
|
|
isFacingAvatar: true
|
|
});
|
|
|
|
var offsetPositionY = 0.2;
|
|
var offsetPositionX = -0.4;
|
|
|
|
for (var i = 0; i < ICONS.length; i++) {
|
|
//print("creating button " + ICONS[i]);
|
|
buttons[i] = new Image3DOverlay({
|
|
url: ICONS[i],
|
|
dimensions: {
|
|
x: 0.15,
|
|
y: 0.15
|
|
},
|
|
isFacingAvatar: false,
|
|
alpha: 0.8,
|
|
ignoreRayIntersection: false,
|
|
offsetPosition: {
|
|
x: offsetPositionX,
|
|
y: offsetPositionY - (i * offsetPositionY),
|
|
z: 0
|
|
},
|
|
});
|
|
|
|
mainPanel.addChild(buttons[i]);
|
|
}
|
|
|
|
|
|
|
|
isUIWorking = true;
|
|
},
|
|
|
|
|
|
collisionWithEntity: function(myID, otherID, collisionInfo) {
|
|
//print("SHOE COLLISION: " + collisionInfo.penetration.x + " - " + collisionInfo.penetration.y + " - " + collisionInfo.penetration.z);
|
|
//var penetrationValue = collisionInfo.penetration.x + collisionInfo.penetration.y + collisionInfo.penetration.z;
|
|
var penetrationValue = Vec3.length(collisionInfo.penetration);
|
|
//print("Value: " + penetrationValue);
|
|
if (penetrationValue > PENETRATION_THRESHOLD && zoneID === null) {
|
|
zoneID = otherID;
|
|
print("Zone: " + zoneID);
|
|
|
|
var itemObj = getEntityCustomData('itemKey', this.entityID, null);
|
|
//print("------- The entity in the inspect zone is: " + ((itemObj == null) ? itemObj : itemObj.itemID));
|
|
|
|
if (itemObj != null) {
|
|
if (itemObj.itemID == otherID) {
|
|
// change overlay color
|
|
//print("Going to call the change color to red");
|
|
Entities.callEntityMethod(otherID, 'changeOverlayColor', null);
|
|
}
|
|
}
|
|
} else if (penetrationValue < PENETRATION_THRESHOLD && zoneID !== null) {
|
|
zoneID = null;
|
|
//print("Zone: " + zoneID);
|
|
//print("Going to call the change color to green");
|
|
Entities.callEntityMethod(otherID, 'changeOverlayColor', null);
|
|
}
|
|
},
|
|
|
|
unload: function (entityID) {
|
|
if(inspectingMyItem){
|
|
print("UNLOAD INSPECT ENTITY");
|
|
Script.update.disconnect(update);
|
|
|
|
// clean UI
|
|
Entities.deleteEntity(_this.entityID);
|
|
}
|
|
}
|
|
};
|
|
return new InspectEntity();
|
|
}) |