mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 22:55:06 +02:00
858 lines
No EOL
36 KiB
JavaScript
858 lines
No EOL
36 KiB
JavaScript
// shopInspectEntityScript.js
|
|
//
|
|
// The inspection entity which runs this entity script will be in fron of the avatar while he's grabbing an item.
|
|
// This script gives some information to the avatar using interactive 3DOverlays:
|
|
// - Drive the customer to put he item in the correct zone to inspect it
|
|
// - Create the UI while inspecting with text and buttons and manages the clicks on them modifying the item and communicating with agents
|
|
// And also it creates the MyController which are in charge to render the rays from the hands during inspecting and analysing their intersection with other overlays
|
|
|
|
// Created by Alessandro Signa and Edgar Pironti on 01/13/2016
|
|
// Copyright 2016 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
|
|
//
|
|
|
|
|
|
(function() {
|
|
|
|
|
|
var utilitiesScript = Script.resolvePath("../../libraries/utils.js");
|
|
var overlayManagerScript = Script.resolvePath("../../libraries/overlayManager.js");
|
|
Script.include(utilitiesScript);
|
|
Script.include(overlayManagerScript);
|
|
|
|
var AGENT_REVIEW_CHANNEL = "reviewChannel";
|
|
var NO_REVIEWS_AVAILABLE = "No reviews available";
|
|
var SEPARATOR = "Separator";
|
|
var CAMERA_REVIEW = "CameraReview";
|
|
|
|
var ZERO_STAR_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/0Star.png";
|
|
var ONE_STAR_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/1Star.png";
|
|
var TWO_STAR_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/2Star.png";
|
|
var THREE_STAR_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/3Star.png";
|
|
|
|
var POINTER_ICON_URL = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/Pointer.png";
|
|
var TRY_ON_ICON = "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/TryOn.png"
|
|
|
|
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: 165,
|
|
green: 199,
|
|
blue: 218
|
|
};
|
|
|
|
var COMFORT_ARM_LENGTH = 0.4;
|
|
|
|
var PENETRATION_THRESHOLD = 0.2;
|
|
|
|
var _this;
|
|
var inspecting = false;
|
|
var inspectingMyItem = false;
|
|
var inspectedEntityID = null;
|
|
var isUIWorking = false;
|
|
var wantToStopTrying = false;
|
|
var rightController = null;
|
|
var leftController = null;
|
|
var workingHand = null;
|
|
var collidedItemID = null;
|
|
var tempTryEntity = null;
|
|
var tryingOnAvatar = false;
|
|
var itemOriginalDimensions = null;
|
|
|
|
var mainPanel = null;
|
|
var mirrorPanel = null;
|
|
var buttons = [];
|
|
var tryOnAvatarButton = null;
|
|
var playButton = null;
|
|
var nextButton = null;
|
|
var textReviewerName = null;
|
|
var modelURLsArray = [];
|
|
var previewURLsArray = [];
|
|
var starURL = null;
|
|
|
|
var reviewIndex = 0;
|
|
var reviewsNumber = 0;
|
|
var dbMatrix = null;
|
|
|
|
var separator = null;
|
|
var cameraReview = null;
|
|
|
|
|
|
var pointer = new Image3DOverlay({ //maybe we want to use one pointer for each hand ?
|
|
url: POINTER_ICON_URL,
|
|
dimensions: {
|
|
x: 0.015,
|
|
y: 0.015
|
|
},
|
|
alpha: 1,
|
|
emissive: true,
|
|
isFacingAvatar: false,
|
|
ignoreRayIntersection: true,
|
|
})
|
|
|
|
|
|
|
|
// 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) {
|
|
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;
|
|
}
|
|
},
|
|
|
|
this.updateRay = function() {
|
|
//update the ray object
|
|
this.pickRay = {
|
|
origin: this.getHandPosition(),
|
|
direction: Quat.getUp(this.getHandRotation())
|
|
};
|
|
|
|
//update the ray overlay and the pointer
|
|
var rayPickResult = OverlayManager.findRayIntersection(this.pickRay);
|
|
if (rayPickResult.intersects) {
|
|
var normal = Vec3.multiply(Quat.getFront(Camera.getOrientation()), -1);
|
|
var offset = Vec3.multiply(normal, 0.001);
|
|
pointer.position = Vec3.sum(rayPickResult.intersection, offset); //pointer is a global Image3DOverlay
|
|
pointer.rotation = Camera.getOrientation();
|
|
pointer.visible = true;
|
|
} else {
|
|
pointer.visible = false;
|
|
}
|
|
|
|
var farPoint = rayPickResult.intersects ? rayPickResult.intersection : Vec3.sum(this.pickRay.origin, Vec3.multiply(this.pickRay.direction, LINE_LENGTH));
|
|
this.overlayLineOn(this.pickRay.origin, farPoint, COLOR);
|
|
|
|
},
|
|
//the update of each hand has to update the ray belonging to that hand and handle the bumper event
|
|
this.updateHand = function() {
|
|
//detect the bumper event
|
|
var bumperPressed = Controller.getValue(this.bumper);
|
|
if (bumperPressed && this != workingHand) {
|
|
workingHand.clean();
|
|
workingHand = this;
|
|
} else if (this != workingHand) {
|
|
return;
|
|
}
|
|
|
|
this.updateRay();
|
|
|
|
//manage event on UI
|
|
if (bumperPressed && !this.waitingForBumpReleased) {
|
|
this.waitingForBumpReleased = true; //to avoid looping on the button while keep pressing the bumper
|
|
var triggeredButton = OverlayManager.findOnRay(this.pickRay);
|
|
if (triggeredButton != null) {
|
|
//search the index of the UI element triggered
|
|
for (var i = 0; i < buttons.length; i++) {
|
|
if (buttons[i] == triggeredButton) {
|
|
|
|
_this.changeModel(i);
|
|
}
|
|
}
|
|
|
|
//the nextButton moves to the next customer review, changing the agent accordingly
|
|
if (nextButton == triggeredButton) {
|
|
|
|
reviewIndex ++;
|
|
if (reviewIndex == reviewsNumber) {
|
|
reviewIndex = 0;
|
|
}
|
|
|
|
var message = {
|
|
command: "Show",
|
|
clip_url: dbMatrix[reviewIndex].clip_url
|
|
};
|
|
|
|
Messages.sendMessage(AGENT_REVIEW_CHANNEL, JSON.stringify(message));
|
|
print("Show sent to agent");
|
|
|
|
// update UI
|
|
textReviewerName.text = dbMatrix[reviewIndex].name;
|
|
reviewerScore.url = starConverter(dbMatrix[reviewIndex].score);
|
|
print("UI updated");
|
|
}
|
|
|
|
//the playButton sends the play command to the agent
|
|
if (playButton == triggeredButton) {
|
|
var message = {
|
|
command: "Play",
|
|
clip_url: dbMatrix[reviewIndex].clip_url
|
|
};
|
|
|
|
Messages.sendMessage(AGENT_REVIEW_CHANNEL, JSON.stringify(message));
|
|
print("Play sent to agent");
|
|
|
|
}
|
|
|
|
//the tryOnAvatarButton change the camera mode and puts t a copy of the inspected item in a proper position on the the avatar
|
|
if (tryOnAvatarButton == triggeredButton) {
|
|
print("tryOnAvatar pressed!");
|
|
|
|
var itemPositionWhileTrying = null;
|
|
//All the offset here are good just for Will avatar increasing its size by one
|
|
switch (Entities.getEntityProperties(inspectedEntityID).name) {
|
|
case "Item_Sunglasses":
|
|
itemPositionWhileTrying = {x: 0, y: 0.04, z: 0.05};
|
|
break;
|
|
case "Item_Hat":
|
|
itemPositionWhileTrying = {x: 0, y: 0.16, z: 0.025};
|
|
break;
|
|
default:
|
|
//there isn't any position specified for that item, use a default one
|
|
itemPositionWhileTrying = {x: 0, y: 0.16, z: 0.025};
|
|
break;
|
|
}
|
|
|
|
//Code for the overlay text for the mirror.
|
|
mirrorPanel = new OverlayPanel({
|
|
anchorPositionBinding: { avatar: "MyAvatar" },
|
|
anchorRotationBinding: { avatar: "MyAvatar" },
|
|
offsetPosition: {
|
|
x: 0.5,
|
|
y: 0.9,
|
|
z: 0
|
|
},
|
|
offsetRotation: Quat.fromVec3Degrees({x: 0, y: 180, z: 0}),
|
|
|
|
isFacingAvatar: false
|
|
});
|
|
var mirrorText = new Text3DOverlay({
|
|
text: "Press the bumper to go back in inspection",
|
|
isFacingAvatar: false,
|
|
ignoreRayIntersection: true,
|
|
|
|
|
|
dimensions: { x: 0, y: 0 },
|
|
backgroundColor: { red: 255, green: 255, blue: 255 },
|
|
color: { red: 200, green: 0, blue: 0 },
|
|
topMargin: 0.00625,
|
|
leftMargin: 0.00625,
|
|
bottomMargin: 0.1,
|
|
rightMargin: 0.00625,
|
|
lineHeight: 0.05,
|
|
alpha: 1,
|
|
backgroundAlpha: 0.3,
|
|
visible: true
|
|
});
|
|
mirrorPanel.addChild(mirrorText);
|
|
|
|
tryingOnAvatar = true;
|
|
|
|
//Clean inspect Overlays and related stuff
|
|
workingHand.clean();
|
|
mainPanel.destroy();
|
|
mainPanel = null;
|
|
isUIWorking = false;
|
|
Entities.editEntity(inspectedEntityID, { visible: false }); //the inspected item becomes invisible
|
|
|
|
|
|
Camera.mode = "entity";
|
|
Camera.cameraEntity = _this.entityID;
|
|
var entityProperties = Entities.getEntityProperties(inspectedEntityID);
|
|
tempTryEntity = Entities.addEntity({
|
|
type: entityProperties.type,
|
|
name: entityProperties.name,
|
|
localPosition: itemPositionWhileTrying,
|
|
dimensions: itemOriginalDimensions,
|
|
collisionsWillMove: false,
|
|
ignoreForCollisions: true,
|
|
modelURL: entityProperties.modelURL,
|
|
shapeType: entityProperties.shapeType,
|
|
originalTextures: entityProperties.originalTextures,
|
|
parentID: MyAvatar.sessionUUID,
|
|
parentJointIndex: MyAvatar.getJointIndex("Head")
|
|
});
|
|
}
|
|
}
|
|
} else if (!bumperPressed && this.waitingForBumpReleased) {
|
|
this.waitingForBumpReleased = false;
|
|
}
|
|
},
|
|
|
|
this.clean = function() {
|
|
this.pickRay = null;
|
|
this.overlayLine.destroy();
|
|
this.overlayLine = null;
|
|
pointer.visible = false;
|
|
}
|
|
};
|
|
|
|
function update(deltaTime) {
|
|
|
|
if (tryingOnAvatar) {
|
|
// if trying the item on avatar, wait for a bumper being pressed to exit this mode
|
|
//the bumper is already pressed when we get here because we triggered the button pressing the bumper so we have to wait it's released
|
|
if(Controller.getValue(workingHand.bumper) && wantToStopTrying) {
|
|
Camera.cameraEntity = null;
|
|
Camera.mode = "first person";
|
|
mirrorPanel.destroy();
|
|
mirrorPanel = null;
|
|
Entities.deleteEntity(tempTryEntity);
|
|
tempTryEntity = null;
|
|
Entities.editEntity(inspectedEntityID, { visible: true });
|
|
_this.createInspectUI();
|
|
tryingOnAvatar = false;
|
|
wantToStopTrying = false;
|
|
} else if (!Controller.getValue(workingHand.bumper) && !wantToStopTrying) {
|
|
//no bumper is pressed
|
|
wantToStopTrying = true;
|
|
}
|
|
return;
|
|
} else 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) {
|
|
//getting here when the inspect phase end, so we want to clean the UI
|
|
// Destroy rays
|
|
workingHand.clean();
|
|
|
|
// Destroy overlay
|
|
mainPanel.destroy();
|
|
isUIWorking = false;
|
|
|
|
var message = {
|
|
command: "Hide",
|
|
clip_url: ""
|
|
};
|
|
|
|
Messages.sendMessage(AGENT_REVIEW_CHANNEL, JSON.stringify(message));
|
|
print("Hide sent to agent");
|
|
|
|
if (separator != null || cameraReview != null) {
|
|
Entities.editEntity(separator, { visible: true });
|
|
Entities.editEntity(separator, { locked: true });
|
|
Entities.editEntity(cameraReview, { visible: true });
|
|
Entities.editEntity(cameraReview, { locked: true });
|
|
}
|
|
}
|
|
|
|
_this.positionRotationUpdate();
|
|
};
|
|
|
|
function starConverter(value) {
|
|
var starURL = ZERO_STAR_URL;
|
|
|
|
switch(value) {
|
|
case 0:
|
|
starURL = ZERO_STAR_URL;
|
|
break;
|
|
|
|
case 1:
|
|
starURL = ONE_STAR_URL;
|
|
break;
|
|
|
|
case 2:
|
|
starURL = TWO_STAR_URL;
|
|
break;
|
|
|
|
case 3:
|
|
starURL = THREE_STAR_URL;
|
|
break;
|
|
|
|
default:
|
|
starURL = ZERO_STAR_URL;
|
|
break;
|
|
}
|
|
|
|
return starURL;
|
|
};
|
|
|
|
|
|
// look for the database entity relative to the inspected item
|
|
function findItemDataBase(entityID, item) {
|
|
var dataBaseID = null;
|
|
var databaseEntityName = item + "DB";
|
|
var entitiesInZone = Entities.findEntities(Entities.getEntityProperties(entityID).position, (Entities.getEntityProperties(entityID).dimensions.x)*100);
|
|
|
|
for (var i = 0; i < entitiesInZone.length && dataBaseID == null; i++) {
|
|
if (Entities.getEntityProperties(entitiesInZone[i]).name == databaseEntityName) {
|
|
dataBaseID = entitiesInZone[i];
|
|
print("Database found! " + entitiesInZone[i]);
|
|
return dataBaseID;
|
|
}
|
|
}
|
|
print("No database for this item.");
|
|
return null;
|
|
};
|
|
|
|
function findItemByName(searchingPointEntityID, itemName) {
|
|
print("Looking for item: " + itemName);
|
|
var entitiesInZone = Entities.findEntities(Entities.getEntityProperties(searchingPointEntityID).position, (Entities.getEntityProperties(searchingPointEntityID).dimensions.x)*100);
|
|
|
|
for (var i = 0; i < entitiesInZone.length; i++) {
|
|
if (Entities.getEntityProperties(entitiesInZone[i]).name == itemName) {
|
|
print(itemName + " found! " + entitiesInZone[i]);
|
|
return entitiesInZone[i];
|
|
}
|
|
}
|
|
print("Item " + itemName + " not found");
|
|
return null;
|
|
};
|
|
|
|
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);
|
|
workingHand = rightController;
|
|
inspectingMyItem = true;
|
|
inspectRadius = (Entities.getEntityProperties(_this.entityID).dimensions.x) / 2 + COMFORT_ARM_LENGTH;
|
|
Script.update.connect(update);
|
|
}
|
|
},
|
|
|
|
//Put the item which calls this method in inspect mode if it belongs to the owner of the inspect zone
|
|
doSomething: function (entityID, dataArray) {
|
|
var data = JSON.parse(dataArray[0]);
|
|
var itemOwnerObj = getEntityCustomData('ownerKey', data.id, null);
|
|
|
|
var inspectOwnerObj = getEntityCustomData('ownerKey', this.entityID, null);
|
|
|
|
if (inspectOwnerObj == null) {
|
|
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
|
|
});
|
|
_this.createInspectUI();
|
|
itemOriginalDimensions = Entities.getEntityProperties(inspectedEntityID).dimensions;
|
|
|
|
// find separator and camera and hide
|
|
separator = findItemByName(inspectedEntityID, SEPARATOR);
|
|
Entities.editEntity(separator, { locked: false });
|
|
Entities.editEntity(separator, { visible: false });
|
|
print("Got here! Entity to hide: " + separator);
|
|
cameraReview = findItemByName(inspectedEntityID, CAMERA_REVIEW);
|
|
Entities.editEntity(cameraReview, { locked: false });
|
|
Entities.editEntity(cameraReview, { visible: false });
|
|
print("Got here! Entity to hide: " + cameraReview);
|
|
} else {
|
|
Entities.deleteEntity(data.id);
|
|
}
|
|
},
|
|
|
|
//make the inspection entity stay at the proper position with respect to the avatar and camera positions
|
|
positionRotationUpdate: function() {
|
|
var newRotation;
|
|
if (tryingOnAvatar) {
|
|
newRotation = Vec3.sum(Quat.safeEulerAngles(MyAvatar.orientation), {x:0, y: 180, z: 0}); //neccessary to set properly the camera in entity mode when trying on avatar
|
|
Entities.editEntity(_this.entityID, { rotation: Quat.fromVec3Degrees(newRotation) });
|
|
} else {
|
|
var newPosition = Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), inspectRadius));
|
|
Entities.editEntity(_this.entityID, { position: newPosition });
|
|
newRotation = MyAvatar.orientation;
|
|
Entities.editEntity(_this.entityID, { rotation: newRotation });
|
|
}
|
|
|
|
newPosition = Vec3.sum(newPosition, Vec3.multiply(Quat.getRight(newRotation), 0.34));
|
|
|
|
},
|
|
|
|
createInspectUI : function() {
|
|
|
|
var infoObj = getEntityCustomData('infoKey', inspectedEntityID, null);
|
|
var itemDescriptionString = null;
|
|
var priceNumber = -1;
|
|
var availabilityNumber = -1;
|
|
var wearable = false;
|
|
|
|
if(infoObj != null) {
|
|
//var modelURLsLoop = infoObj.modelURLs; ??
|
|
var rootURLString = infoObj.rootURL;
|
|
for (var i = 0; i < infoObj.modelURLs.length; i++) {
|
|
modelURLsArray[i] = rootURLString + infoObj.modelURLs[i];
|
|
previewURLsArray[i] = rootURLString + infoObj.previewURLs[i];
|
|
}
|
|
|
|
itemDescriptionString = infoObj.description;
|
|
priceNumber = infoObj.price;
|
|
availabilityNumber = infoObj.availability;
|
|
wearable = infoObj.wearable;
|
|
infoObj = null;
|
|
}
|
|
|
|
//Looking for the item DB, this entity has in its userData the info of the customer reviews for the item
|
|
var DBID = findItemDataBase(_this.entityID, Entities.getEntityProperties(inspectedEntityID).name);
|
|
|
|
if (DBID != null) {
|
|
infoObj = getEntityCustomData('infoKey', DBID, null);
|
|
var scoreAverage = null;
|
|
var reviewerName = null;
|
|
|
|
if(infoObj != null) {
|
|
dbMatrix = infoObj.dbKey;
|
|
reviewsNumber = infoObj.dbKey.length;
|
|
//print("DB matrix is " + dbMatrix + " with element number: " + reviewsNumber);
|
|
var scoreSum = null;
|
|
|
|
for (var i = 0; i < dbMatrix.length; i++) {
|
|
scoreSum += dbMatrix[i].score;
|
|
}
|
|
|
|
if (dbMatrix.length) {
|
|
scoreAverage = Math.round(scoreSum / dbMatrix.length);
|
|
reviewerName = dbMatrix[reviewIndex].name;
|
|
|
|
var message = {
|
|
command: "Show",
|
|
clip_url: dbMatrix[reviewIndex].clip_url
|
|
};
|
|
|
|
Messages.sendMessage(AGENT_REVIEW_CHANNEL, JSON.stringify(message));
|
|
print("Show sent to agent");
|
|
} else {
|
|
//some default value if the DB is empty
|
|
scoreAverage = 0;
|
|
reviewerName = NO_REVIEWS_AVAILABLE;
|
|
}
|
|
|
|
}
|
|
|
|
print ("Creating inspect UI");
|
|
//set the main panel to follow the inspect entity
|
|
mainPanel = new OverlayPanel({
|
|
anchorPositionBinding: { entity: _this.entityID },
|
|
anchorRotationBinding: { entity: _this.entityID },
|
|
isFacingAvatar: false
|
|
});
|
|
|
|
var offsetPositionY = 0.2;
|
|
var offsetPositionX = -0.4;
|
|
|
|
//these buttons are the 3 previews of the item
|
|
for (var i = 0; i < previewURLsArray.length; i++) {
|
|
buttons[i] = new Image3DOverlay({
|
|
url: previewURLsArray[i],
|
|
dimensions: {
|
|
x: 0.15,
|
|
y: 0.15
|
|
},
|
|
isFacingAvatar: false,
|
|
alpha: 0.8,
|
|
ignoreRayIntersection: false,
|
|
offsetPosition: {
|
|
x: offsetPositionX,
|
|
y: offsetPositionY - (i * offsetPositionY),
|
|
z: 0
|
|
},
|
|
emissive: true,
|
|
});
|
|
|
|
mainPanel.addChild(buttons[i]);
|
|
}
|
|
|
|
//aggregateScore is the average between those given by the reviewers
|
|
var aggregateScore = new Image3DOverlay({
|
|
url: starConverter(scoreAverage),
|
|
dimensions: {
|
|
x: 0.25,
|
|
y: 0.25
|
|
},
|
|
isFacingAvatar: false,
|
|
alpha: 1,
|
|
ignoreRayIntersection: true,
|
|
offsetPosition: {
|
|
x: 0,
|
|
y: 0.27,
|
|
z: 0
|
|
},
|
|
emissive: true,
|
|
});
|
|
|
|
mainPanel.addChild(aggregateScore);
|
|
|
|
//if any review is available create buttons to manage them
|
|
if (dbMatrix.length) {
|
|
|
|
playButton = new Image3DOverlay({
|
|
url: "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/Play.png",
|
|
dimensions: {
|
|
x: 0.08,
|
|
y: 0.08
|
|
},
|
|
isFacingAvatar: false,
|
|
alpha: 1,
|
|
ignoreRayIntersection: false,
|
|
offsetPosition: {
|
|
x: 0.42,
|
|
y: 0.27,
|
|
z: 0
|
|
},
|
|
emissive: true,
|
|
});
|
|
|
|
mainPanel.addChild(playButton);
|
|
|
|
|
|
reviewerScore = new Image3DOverlay({
|
|
url: starConverter(dbMatrix[reviewIndex].score),
|
|
dimensions: {
|
|
x: 0.15,
|
|
y: 0.15
|
|
},
|
|
isFacingAvatar: false,
|
|
alpha: 1,
|
|
ignoreRayIntersection: true,
|
|
offsetPosition: {
|
|
x: 0.31,
|
|
y: 0.26,
|
|
z: 0
|
|
},
|
|
emissive: true,
|
|
});
|
|
|
|
mainPanel.addChild(reviewerScore);
|
|
|
|
nextButton = new Image3DOverlay({
|
|
url: "https://dl.dropboxusercontent.com/u/14127429/FBX/VRshop/Next.png",
|
|
dimensions: {
|
|
x: 0.2,
|
|
y: 0.2
|
|
},
|
|
isFacingAvatar: false,
|
|
alpha: 1,
|
|
ignoreRayIntersection: false,
|
|
offsetPosition: {
|
|
x: 0.36,
|
|
y: 0.18,
|
|
z: 0
|
|
},
|
|
emissive: true,
|
|
});
|
|
|
|
|
|
mainPanel.addChild(nextButton);
|
|
|
|
}
|
|
|
|
textReviewerName = new Text3DOverlay({
|
|
text: reviewerName,
|
|
isFacingAvatar: false,
|
|
alpha: 1.0,
|
|
ignoreRayIntersection: true,
|
|
offsetPosition: {
|
|
x: 0.23,
|
|
y: 0.31,
|
|
z: 0
|
|
},
|
|
dimensions: { x: 0, y: 0 },
|
|
backgroundColor: { red: 255, green: 255, blue: 255 },
|
|
color: { red: 0, green: 0, blue: 0 },
|
|
topMargin: 0.00625,
|
|
leftMargin: 0.00625,
|
|
bottomMargin: 0.1,
|
|
rightMargin: 0.00625,
|
|
lineHeight: 0.02,
|
|
alpha: 1,
|
|
backgroundAlpha: 0.3
|
|
});
|
|
|
|
mainPanel.addChild(textReviewerName);
|
|
|
|
//if the item is wearable create a tryOnAvatarButton
|
|
if (wearable) {
|
|
tryOnAvatarButton = new Image3DOverlay({
|
|
url: TRY_ON_ICON,
|
|
dimensions: {
|
|
x: 0.2,
|
|
y: 0.2
|
|
},
|
|
isFacingAvatar: false,
|
|
alpha: 1,
|
|
ignoreRayIntersection: false,
|
|
offsetPosition: {
|
|
x: 0.35,
|
|
y: -0.22,
|
|
z: 0
|
|
},
|
|
emissive: true,
|
|
});
|
|
|
|
mainPanel.addChild(tryOnAvatarButton);
|
|
}
|
|
|
|
|
|
var textQuantityString = new Text3DOverlay({
|
|
text: "Quantity: ",
|
|
isFacingAvatar: false,
|
|
alpha: 1.0,
|
|
ignoreRayIntersection: true,
|
|
offsetPosition: {
|
|
x: 0.25,
|
|
y: -0.3,
|
|
z: 0
|
|
},
|
|
dimensions: { x: 0, y: 0 },
|
|
backgroundColor: { red: 255, green: 255, blue: 255 },
|
|
color: { red: 0, green: 0, blue: 0 },
|
|
topMargin: 0.00625,
|
|
leftMargin: 0.00625,
|
|
bottomMargin: 0.1,
|
|
rightMargin: 0.00625,
|
|
lineHeight: 0.02,
|
|
alpha: 1,
|
|
backgroundAlpha: 0.3
|
|
});
|
|
|
|
mainPanel.addChild(textQuantityString);
|
|
|
|
var textQuantityNumber = new Text3DOverlay({
|
|
text: availabilityNumber,
|
|
isFacingAvatar: false,
|
|
alpha: 1.0,
|
|
ignoreRayIntersection: true,
|
|
offsetPosition: {
|
|
x: 0.28,
|
|
y: -0.32,
|
|
z: 0
|
|
},
|
|
dimensions: { x: 0, y: 0 },
|
|
backgroundColor: { red: 255, green: 255, blue: 255 },
|
|
color: { red: 0, green: 0, blue: 0 },
|
|
topMargin: 0.00625,
|
|
leftMargin: 0.00625,
|
|
bottomMargin: 0.1,
|
|
rightMargin: 0.00625,
|
|
lineHeight: 0.06,
|
|
alpha: 1,
|
|
backgroundAlpha: 0.3
|
|
});
|
|
|
|
mainPanel.addChild(textQuantityNumber);
|
|
|
|
if (itemDescriptionString != null) {
|
|
var textDescription = new Text3DOverlay({
|
|
text: "Price: " + priceNumber + "\nAdditional information: \n" + itemDescriptionString,
|
|
isFacingAvatar: false,
|
|
alpha: 1.0,
|
|
ignoreRayIntersection: true,
|
|
offsetPosition: {
|
|
x: -0.2,
|
|
y: -0.3,
|
|
z: 0
|
|
},
|
|
dimensions: { x: 0, y: 0 },
|
|
backgroundColor: { red: 255, green: 255, blue: 255 },
|
|
color: { red: 0, green: 0, blue: 0 },
|
|
topMargin: 0.00625,
|
|
leftMargin: 0.00625,
|
|
bottomMargin: 0.1,
|
|
rightMargin: 0.00625,
|
|
lineHeight: 0.02,
|
|
alpha: 1,
|
|
backgroundAlpha: 0.3
|
|
});
|
|
|
|
mainPanel.addChild(textDescription);
|
|
}
|
|
|
|
|
|
|
|
print ("GOT HERE: Descrition " + itemDescriptionString + " Availability " + availabilityNumber);
|
|
|
|
isUIWorking = true;
|
|
}
|
|
},
|
|
|
|
//Manage the collisions and tell to the item if it is into the this inspection area
|
|
collisionWithEntity: function(myID, otherID, collisionInfo) {
|
|
|
|
var itemObj = getEntityCustomData('itemKey', _this.entityID, null);
|
|
if (itemObj != null) {
|
|
if (itemObj.itemID == otherID) { //verify that the inspect area is colliding with the actual item which created it
|
|
|
|
var penetrationValue = Vec3.length(collisionInfo.penetration);
|
|
if (penetrationValue > PENETRATION_THRESHOLD && collidedItemID === null) {
|
|
collidedItemID = otherID;
|
|
print("Start collision with: " + Entities.getEntityProperties(collidedItemID).name);
|
|
Entities.callEntityMethod(otherID, 'changeOverlayColor', null);
|
|
|
|
} else if (penetrationValue < PENETRATION_THRESHOLD && collidedItemID !== null) {
|
|
|
|
print("End collision with: " + Entities.getEntityProperties(collidedItemID).name);
|
|
collidedItemID = null;
|
|
Entities.callEntityMethod(otherID, 'changeOverlayColor', null);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
changeModel: function(index) {
|
|
var entityProperties = Entities.getEntityProperties(inspectedEntityID);
|
|
if (entityProperties.modelURL != modelURLsArray[index]) {
|
|
Entities.editEntity(inspectedEntityID, { modelURL: modelURLsArray[index] });
|
|
}
|
|
},
|
|
|
|
unload: function (entityID) {
|
|
if(inspectingMyItem){
|
|
print("UNLOAD INSPECT ENTITY");
|
|
Script.update.disconnect(update);
|
|
|
|
// clean UI
|
|
Entities.deleteEntity(_this.entityID);
|
|
}
|
|
}
|
|
};
|
|
return new InspectEntity();
|
|
}) |