Andrew Meadowsarchive remaining JS scriptsc0b446c10 years agoHistory
858 lines · 35.8 KB · JavaScript
RawDownload
// 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 {

Lines 1–500 of 858.